4 * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
5 * redistributed under the terms of the GNU Public License.
10 #define _GNU_SOURCE 1 /* get strnlen() */
12 #include <sys/types.h>
30 #include <sys/resource.h>
31 #include <sys/param.h>
32 #include <sys/mount.h>
33 #include <sys/ioctl.h>
41 #include "ext2fs/ext2_fs.h"
42 #include "ext2fs/ext2fs.h"
43 #include "blkid/blkid.h"
44 #include "ext2fs/ext2_ext_attr.h"
45 #include "uuid/uuid.h"
48 #define _INLINE_ __inline__
49 #define EXT2FS_ATTR(x) __attribute__(x)
52 #define EXT2FS_ATTR(x)
56 * Exit codes used by fsck-type programs
58 #define FSCK_OK 0 /* No errors */
59 #define FSCK_NONDESTRUCT 1 /* File system errors corrected */
60 #define FSCK_REBOOT 2 /* System should be rebooted */
61 #define FSCK_UNCORRECTED 4 /* File system errors left uncorrected */
62 #define FSCK_ERROR 8 /* Operational error */
63 #define FSCK_USAGE 16 /* Usage or syntax error */
64 #define FSCK_CANCELED 32 /* Aborted with a signal or ^C */
65 #define FSCK_LIBRARY 128 /* Shared library error */
68 * The last ext2fs revision level that this version of e2fsck is able to
71 #define E2FSCK_CURRENT_REV 1
74 * The directory information structure; stores directory information
75 * collected in earlier passes, to avoid disk i/o in fetching the
76 * directory information.
79 ext2_ino_t ino; /* Inode number */
80 ext2_ino_t dotdot; /* Parent according to '..' */
81 ext2_ino_t parent; /* Parent according to treewalk */
86 * The indexed directory information structure; stores information for
87 * directories which contain a hash tree index.
90 ext2_ino_t ino; /* Inode number */
91 int numblocks; /* number of blocks */
93 short depth; /* depth of tree */
94 struct dx_dirblock_info *dx_block; /* Array of size numblocks */
97 #define DX_DIRBLOCK_ROOT 1
98 #define DX_DIRBLOCK_LEAF 2
99 #define DX_DIRBLOCK_NODE 3
100 #define DX_DIRBLOCK_CORRUPT 4
101 #define DX_DIRBLOCK_CLEARED 8
103 struct dx_dirblock_info {
108 ext2_dirhash_t min_hash;
109 ext2_dirhash_t max_hash;
110 ext2_dirhash_t node_min_hash;
111 ext2_dirhash_t node_max_hash;
114 #define DX_FLAG_REFERENCED 1
115 #define DX_FLAG_DUP_REF 2
116 #define DX_FLAG_FIRST 4
117 #define DX_FLAG_LAST 8
119 #ifdef RESOURCE_TRACK
121 * This structure is used for keeping track of how much resources have
122 * been used for a particular pass of e2fsck.
124 struct resource_track {
125 struct timeval time_start;
126 struct timeval user_start;
127 struct timeval system_start;
135 #define E2F_OPT_READONLY 0x0001
136 #define E2F_OPT_PREEN 0x0002
137 #define E2F_OPT_YES 0x0004
138 #define E2F_OPT_NO 0x0008
139 #define E2F_OPT_TIME 0x0010
140 #define E2F_OPT_TIME2 0x0020
141 #define E2F_OPT_CHECKBLOCKS 0x0040
142 #define E2F_OPT_DEBUG 0x0080
143 #define E2F_OPT_FORCE 0x0100
144 #define E2F_OPT_WRITECHECK 0x0200
145 #define E2F_OPT_COMPRESS_DIRS 0x0400
150 #define E2F_FLAG_ABORT 0x0001 /* Abort signaled */
151 #define E2F_FLAG_CANCEL 0x0002 /* Cancel signaled */
152 #define E2F_FLAG_SIGNAL_MASK 0x0003
153 #define E2F_FLAG_RESTART 0x0004 /* Restart signaled */
155 #define E2F_FLAG_SETJMP_OK 0x0010 /* Setjmp valid for abort */
157 #define E2F_FLAG_PROG_BAR 0x0020 /* Progress bar on screen */
158 #define E2F_FLAG_PROG_SUPPRESS 0x0040 /* Progress suspended */
159 #define E2F_FLAG_JOURNAL_INODE 0x0080 /* Create a new ext3 journal inode */
160 #define E2F_FLAG_SB_SPECIFIED 0x0100 /* The superblock was explicitly
161 * specified by the user */
162 #define E2F_FLAG_RESTARTED 0x0200 /* E2fsck has been restarted */
163 #define E2F_FLAG_RESIZE_INODE 0x0400 /* Request to recreate resize inode */
166 * Defines for indicating the e2fsck pass number
173 #define E2F_PASS_1B 6
176 * Define the extended attribute refcount structure
178 typedef struct ea_refcount *ext2_refcount_t;
181 * This is the global e2fsck structure.
183 typedef struct e2fsck_struct *e2fsck_t;
185 struct e2fsck_struct {
187 const char *program_name;
188 char *filesystem_name;
191 int flags; /* E2fsck internal flags */
193 blk_t use_superblock; /* sb requested by user */
194 blk_t superblock; /* sb used to open fs */
195 int blocksize; /* blocksize */
196 blk_t num_blocks; /* Total number of blocks */
198 blkid_cache blkid; /* blkid cache */
202 unsigned long abort_code;
204 int (*progress)(e2fsck_t ctx, int pass, unsigned long cur,
207 ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */
208 ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */
209 ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
210 ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */
211 ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */
212 ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/
214 ext2fs_block_bitmap block_found_map; /* Blocks which are in use */
215 ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */
216 ext2fs_block_bitmap block_ea_map; /* Blocks which are used by EA's */
221 ext2_icount_t inode_count;
222 ext2_icount_t inode_link_info;
224 ext2_refcount_t refcount;
225 ext2_refcount_t refcount_extra;
228 * Array of flags indicating whether an inode bitmap, block
229 * bitmap, or inode table is invalid
231 int *invalid_inode_bitmap_flag;
232 int *invalid_block_bitmap_flag;
233 int *invalid_inode_table_flag;
234 int invalid_bitmaps; /* There are invalid bitmaps/itable */
242 * For pass1_check_directory and pass1_get_blocks
244 ext2_ino_t stashed_ino;
245 struct ext2_inode *stashed_inode;
248 * Location of the lost and found directory
250 ext2_ino_t lost_and_found;
251 int bad_lost_and_found;
254 * Directory information
258 struct dir_info *dir_info;
261 * Indexed directory information
263 int dx_dir_info_count;
264 int dx_dir_info_size;
265 struct dx_dir_info *dx_dir_info;
268 * Directories to hash
270 ext2_u32_list dirs_to_hash;
275 int process_inode_size;
276 int inode_buffer_blocks;
279 * ext3 journal support
281 io_channel journal_io;
284 #ifdef RESOURCE_TRACK
286 * For timing purposes
288 struct resource_track global_rtrack;
292 * How we display the progress update (for unix)
296 int progress_last_percent;
297 unsigned int progress_last_time;
298 int interactive; /* Are we connected directly to a tty? */
299 char start_meta[2], stop_meta[2];
302 int fs_directory_count;
303 int fs_regular_count;
304 int fs_blockdev_count;
305 int fs_chardev_count;
307 int fs_symlinks_count;
308 int fs_fast_symlinks_count;
311 int fs_badblocks_count;
312 int fs_sockets_count;
318 int fs_ext_attr_inodes;
319 int fs_ext_attr_blocks;
324 * For the use of callers of the e2fsck functions; not used by
325 * e2fsck functions themselves.
330 /* Used by the region allocation code */
331 typedef __u32 region_addr_t;
332 typedef struct region_struct *region_t;
335 * Procedure declarations
338 static void e2fsck_pass1(e2fsck_t ctx);
339 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
340 static void e2fsck_pass2(e2fsck_t ctx);
341 static void e2fsck_pass3(e2fsck_t ctx);
342 static void e2fsck_pass4(e2fsck_t ctx);
343 static void e2fsck_pass5(e2fsck_t ctx);
346 static errcode_t e2fsck_allocate_context(e2fsck_t *ret);
347 static errcode_t e2fsck_reset_context(e2fsck_t ctx);
348 static void e2fsck_free_context(e2fsck_t ctx);
349 static int e2fsck_run(e2fsck_t ctx);
353 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
354 int replace_bad_blocks);
357 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent);
358 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino);
359 static void e2fsck_free_dir_info(e2fsck_t ctx);
360 static int e2fsck_get_num_dirinfo(e2fsck_t ctx);
361 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control);
364 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks);
365 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino);
366 static void e2fsck_free_dx_dir_info(e2fsck_t ctx);
367 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control);
370 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret);
371 static void ea_refcount_free(ext2_refcount_t refcount);
372 static errcode_t ea_refcount_increment(ext2_refcount_t refcount,
373 blk_t blk, int *ret);
374 static errcode_t ea_refcount_decrement(ext2_refcount_t refcount,
375 blk_t blk, int *ret);
376 static errcode_t ea_refcount_store(ext2_refcount_t refcount,
377 blk_t blk, int count);
378 static void ea_refcount_intr_begin(ext2_refcount_t refcount);
379 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret);
382 static const char *ehandler_operation(const char *op);
383 static void ehandler_init(io_channel channel);
386 static int e2fsck_check_ext3_journal(e2fsck_t ctx);
387 static int e2fsck_run_ext3_journal(e2fsck_t ctx);
388 static void e2fsck_move_ext3_journal(e2fsck_t ctx);
391 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
392 static int e2fsck_pass1_check_device_inode(ext2_filsys fs,
393 struct ext2_inode *inode);
394 static int e2fsck_pass1_check_symlink(ext2_filsys fs,
395 struct ext2_inode *inode, char *buf);
398 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
399 ext2_ino_t ino, char *buf);
402 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
403 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
404 int num, int gauranteed_size);
405 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
406 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
411 static region_t region_create(region_addr_t min, region_addr_t max);
412 static void region_free(region_t region);
413 static int region_allocate(region_t region, region_addr_t start, int n);
416 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino);
417 static void e2fsck_rehash_directories(e2fsck_t ctx);
420 static void check_super_block(e2fsck_t ctx);
421 static errcode_t e2fsck_get_device_size(e2fsck_t ctx);
425 static void swap_filesys(e2fsck_t ctx);
429 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
430 const char *description);
431 static int ask(e2fsck_t ctx, const char * string, int def);
432 static int ask_yn(const char * string, int def);
433 static void e2fsck_read_bitmaps(e2fsck_t ctx);
434 static void e2fsck_write_bitmaps(e2fsck_t ctx);
435 static void preenhalt(e2fsck_t ctx);
436 static char *string_copy(e2fsck_t ctx, const char *str, int len);
437 #ifdef RESOURCE_TRACK
438 static void print_resource_track(const char *desc,
439 struct resource_track *track);
440 static void init_resource_track(struct resource_track *track);
442 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
443 struct ext2_inode * inode, const char * proc);
444 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
445 struct ext2_inode * inode, const char * proc);
447 static void mtrace_print(char *mesg);
449 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
450 const char *name, io_manager manager);
451 static int ext2_file_type(unsigned int mode);
454 static void e2fsck_clear_progbar(e2fsck_t ctx);
455 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
456 float percent, unsigned int dpynum);
458 * problem.h --- e2fsck problem error codes
461 typedef __u32 problem_t;
463 struct problem_context {
465 ext2_ino_t ino, ino2, dir;
466 struct ext2_inode *inode;
467 struct ext2_dir_entry *dirent;
469 e2_blkcnt_t blkcount;
476 * We define a set of "latch groups"; these are problems which are
477 * handled as a set. The user answers once for a particular latch
480 #define PR_LATCH_MASK 0x0ff0 /* Latch mask */
481 #define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */
482 #define PR_LATCH_BBLOCK 0x0020 /* Latch for bad block inode blocks (pass 1) */
483 #define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */
484 #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */
485 #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */
486 #define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */
487 #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
488 #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */
489 #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */
491 #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1)
494 * Latch group descriptor flags
496 #define PRL_YES 0x0001 /* Answer yes */
497 #define PRL_NO 0x0002 /* Answer no */
498 #define PRL_LATCHED 0x0004 /* The latch group is latched */
499 #define PRL_SUPPRESS 0x0008 /* Suppress all latch group questions */
501 #define PRL_VARIABLE 0x000f /* All the flags that need to be reset */
507 /* Block bitmap not in group */
508 #define PR_0_BB_NOT_GROUP 0x000001
510 /* Inode bitmap not in group */
511 #define PR_0_IB_NOT_GROUP 0x000002
513 /* Inode table not in group */
514 #define PR_0_ITABLE_NOT_GROUP 0x000003
516 /* Superblock corrupt */
517 #define PR_0_SB_CORRUPT 0x000004
519 /* Filesystem size is wrong */
520 #define PR_0_FS_SIZE_WRONG 0x000005
522 /* Fragments not supported */
523 #define PR_0_NO_FRAGMENTS 0x000006
525 /* Bad blocks_per_group */
526 #define PR_0_BLOCKS_PER_GROUP 0x000007
528 /* Bad first_data_block */
529 #define PR_0_FIRST_DATA_BLOCK 0x000008
531 /* Adding UUID to filesystem */
532 #define PR_0_ADD_UUID 0x000009
535 #define PR_0_RELOCATE_HINT 0x00000A
537 /* Miscellaneous superblock corruption */
538 #define PR_0_MISC_CORRUPT_SUPER 0x00000B
540 /* Error determing physical device size of filesystem */
541 #define PR_0_GETSIZE_ERROR 0x00000C
543 /* Inode count in the superblock incorrect */
544 #define PR_0_INODE_COUNT_WRONG 0x00000D
546 /* The Hurd does not support the filetype feature */
547 #define PR_0_HURD_CLEAR_FILETYPE 0x00000E
549 /* Journal inode is invalid */
550 #define PR_0_JOURNAL_BAD_INODE 0x00000F
552 /* The external journal has multiple filesystems (which we can't handle yet) */
553 #define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010
555 /* Can't find external journal */
556 #define PR_0_CANT_FIND_JOURNAL 0x000011
558 /* External journal has bad superblock */
559 #define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012
561 /* Superblock has a bad journal UUID */
562 #define PR_0_JOURNAL_BAD_UUID 0x000013
564 /* Journal has an unknown superblock type */
565 #define PR_0_JOURNAL_UNSUPP_SUPER 0x000014
567 /* Journal superblock is corrupt */
568 #define PR_0_JOURNAL_BAD_SUPER 0x000015
570 /* Journal superblock is corrupt */
571 #define PR_0_JOURNAL_HAS_JOURNAL 0x000016
573 /* Superblock has recovery flag set but no journal */
574 #define PR_0_JOURNAL_RECOVER_SET 0x000017
576 /* Journal has data, but recovery flag is clear */
577 #define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018
579 /* Ask if we should clear the journal */
580 #define PR_0_JOURNAL_RESET_JOURNAL 0x000019
582 /* Filesystem revision is 0, but feature flags are set */
583 #define PR_0_FS_REV_LEVEL 0x00001A
585 /* Clearing orphan inode */
586 #define PR_0_ORPHAN_CLEAR_INODE 0x000020
588 /* Illegal block found in orphaned inode */
589 #define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021
591 /* Already cleared block found in orphaned inode */
592 #define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
594 /* Illegal orphan inode in superblock */
595 #define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023
597 /* Illegal inode in orphaned inode list */
598 #define PR_0_ORPHAN_ILLEGAL_INODE 0x000024
600 /* Journal has unsupported read-only feature - abort */
601 #define PR_0_JOURNAL_UNSUPP_ROCOMPAT 0x000025
603 /* Journal has unsupported incompatible feature - abort */
604 #define PR_0_JOURNAL_UNSUPP_INCOMPAT 0x000026
606 /* Journal has unsupported version number */
607 #define PR_0_JOURNAL_UNSUPP_VERSION 0x000027
609 /* Moving journal to hidden file */
610 #define PR_0_MOVE_JOURNAL 0x000028
612 /* Error moving journal */
613 #define PR_0_ERR_MOVE_JOURNAL 0x000029
615 /* Clearing V2 journal superblock */
616 #define PR_0_CLEAR_V2_JOURNAL 0x00002A
618 /* Run journal anyway */
619 #define PR_0_JOURNAL_RUN 0x00002B
621 /* Run journal anyway by default */
622 #define PR_0_JOURNAL_RUN_DEFAULT 0x00002C
624 /* Backup journal inode blocks */
625 #define PR_0_BACKUP_JNL 0x00002D
627 /* Reserved blocks w/o resize_inode */
628 #define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E
630 /* Resize_inode not enabled, but resize inode is non-zero */
631 #define PR_0_CLEAR_RESIZE_INODE 0x00002F
633 /* Resize inode invalid */
634 #define PR_0_RESIZE_INODE_INVALID 0x000030
640 /* Pass 1: Checking inodes, blocks, and sizes */
641 #define PR_1_PASS_HEADER 0x010000
643 /* Root directory is not an inode */
644 #define PR_1_ROOT_NO_DIR 0x010001
646 /* Root directory has dtime set */
647 #define PR_1_ROOT_DTIME 0x010002
649 /* Reserved inode has bad mode */
650 #define PR_1_RESERVED_BAD_MODE 0x010003
652 /* Deleted inode has zero dtime */
653 #define PR_1_ZERO_DTIME 0x010004
655 /* Inode in use, but dtime set */
656 #define PR_1_SET_DTIME 0x010005
658 /* Zero-length directory */
659 #define PR_1_ZERO_LENGTH_DIR 0x010006
661 /* Block bitmap conflicts with some other fs block */
662 #define PR_1_BB_CONFLICT 0x010007
664 /* Inode bitmap conflicts with some other fs block */
665 #define PR_1_IB_CONFLICT 0x010008
667 /* Inode table conflicts with some other fs block */
668 #define PR_1_ITABLE_CONFLICT 0x010009
670 /* Block bitmap is on a bad block */
671 #define PR_1_BB_BAD_BLOCK 0x01000A
673 /* Inode bitmap is on a bad block */
674 #define PR_1_IB_BAD_BLOCK 0x01000B
676 /* Inode has incorrect i_size */
677 #define PR_1_BAD_I_SIZE 0x01000C
679 /* Inode has incorrect i_blocks */
680 #define PR_1_BAD_I_BLOCKS 0x01000D
682 /* Illegal block number in inode */
683 #define PR_1_ILLEGAL_BLOCK_NUM 0x01000E
685 /* Block number overlaps fs metadata */
686 #define PR_1_BLOCK_OVERLAPS_METADATA 0x01000F
688 /* Inode has illegal blocks (latch question) */
689 #define PR_1_INODE_BLOCK_LATCH 0x010010
691 /* Too many bad blocks in inode */
692 #define PR_1_TOO_MANY_BAD_BLOCKS 0x010011
694 /* Illegal block number in bad block inode */
695 #define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012
697 /* Bad block inode has illegal blocks (latch question) */
698 #define PR_1_INODE_BBLOCK_LATCH 0x010013
700 /* Duplicate or bad blocks in use! */
701 #define PR_1_DUP_BLOCKS_PREENSTOP 0x010014
703 /* Bad block used as bad block indirect block */
704 #define PR_1_BBINODE_BAD_METABLOCK 0x010015
706 /* Inconsistency can't be fixed prompt */
707 #define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
709 /* Bad primary block */
710 #define PR_1_BAD_PRIMARY_BLOCK 0x010017
712 /* Bad primary block prompt */
713 #define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018
715 /* Bad primary superblock */
716 #define PR_1_BAD_PRIMARY_SUPERBLOCK 0x010019
718 /* Bad primary block group descriptors */
719 #define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A
721 /* Bad superblock in group */
722 #define PR_1_BAD_SUPERBLOCK 0x01001B
724 /* Bad block group descriptors in group */
725 #define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C
727 /* Block claimed for no reason */
728 #define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D
730 /* Error allocating blocks for relocating metadata */
731 #define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E
733 /* Error allocating block buffer during relocation process */
734 #define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F
736 /* Relocating metadata group information from X to Y */
737 #define PR_1_RELOC_FROM_TO 0x010020
739 /* Relocating metatdata group information to X */
740 #define PR_1_RELOC_TO 0x010021
742 /* Block read error during relocation process */
743 #define PR_1_RELOC_READ_ERR 0x010022
745 /* Block write error during relocation process */
746 #define PR_1_RELOC_WRITE_ERR 0x010023
748 /* Error allocating inode bitmap */
749 #define PR_1_ALLOCATE_IBITMAP_ERROR 0x010024
751 /* Error allocating block bitmap */
752 #define PR_1_ALLOCATE_BBITMAP_ERROR 0x010025
754 /* Error allocating icount structure */
755 #define PR_1_ALLOCATE_ICOUNT 0x010026
757 /* Error allocating dbcount */
758 #define PR_1_ALLOCATE_DBCOUNT 0x010027
760 /* Error while scanning inodes */
761 #define PR_1_ISCAN_ERROR 0x010028
763 /* Error while iterating over blocks */
764 #define PR_1_BLOCK_ITERATE 0x010029
766 /* Error while storing inode count information */
767 #define PR_1_ICOUNT_STORE 0x01002A
769 /* Error while storing directory block information */
770 #define PR_1_ADD_DBLOCK 0x01002B
772 /* Error while reading inode (for clearing) */
773 #define PR_1_READ_INODE 0x01002C
775 /* Suppress messages prompt */
776 #define PR_1_SUPPRESS_MESSAGES 0x01002D
778 /* Imagic flag set on an inode when filesystem doesn't support it */
779 #define PR_1_SET_IMAGIC 0x01002F
781 /* Immutable flag set on a device or socket inode */
782 #define PR_1_SET_IMMUTABLE 0x010030
784 /* Compression flag set on a non-compressed filesystem */
785 #define PR_1_COMPR_SET 0x010031
787 /* Non-zero size on on device, fifo or socket inode */
788 #define PR_1_SET_NONZSIZE 0x010032
790 /* Filesystem revision is 0, but feature flags are set */
791 #define PR_1_FS_REV_LEVEL 0x010033
793 /* Journal inode not in use, needs clearing */
794 #define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034
796 /* Journal inode has wrong mode */
797 #define PR_1_JOURNAL_BAD_MODE 0x010035
799 /* Inode that was part of orphan linked list */
800 #define PR_1_LOW_DTIME 0x010036
802 /* Latch question which asks how to deal with low dtime inodes */
803 #define PR_1_ORPHAN_LIST_REFUGEES 0x010037
805 /* Error allocating refcount structure */
806 #define PR_1_ALLOCATE_REFCOUNT 0x010038
808 /* Error reading Extended Attribute block */
809 #define PR_1_READ_EA_BLOCK 0x010039
811 /* Invalid Extended Attribute block */
812 #define PR_1_BAD_EA_BLOCK 0x01003A
814 /* Error reading Extended Attribute block while fixing refcount -- abort */
815 #define PR_1_EXTATTR_READ_ABORT 0x01003B
817 /* Extended attribute reference count incorrect */
818 #define PR_1_EXTATTR_REFCOUNT 0x01003C
820 /* Error writing Extended Attribute block while fixing refcount */
821 #define PR_1_EXTATTR_WRITE 0x01003D
823 /* Multiple EA blocks not supported */
824 #define PR_1_EA_MULTI_BLOCK 0x01003E
826 /* Error allocating EA region allocation structure */
827 #define PR_1_EA_ALLOC_REGION 0x01003F
829 /* Error EA allocation collision */
830 #define PR_1_EA_ALLOC_COLLISION 0x010040
832 /* Bad extended attribute name */
833 #define PR_1_EA_BAD_NAME 0x010041
835 /* Bad extended attribute value */
836 #define PR_1_EA_BAD_VALUE 0x010042
838 /* Inode too big (latch question) */
839 #define PR_1_INODE_TOOBIG 0x010043
841 /* Directory too big */
842 #define PR_1_TOOBIG_DIR 0x010044
844 /* Regular file too big */
845 #define PR_1_TOOBIG_REG 0x010045
847 /* Symlink too big */
848 #define PR_1_TOOBIG_SYMLINK 0x010046
850 /* INDEX_FL flag set on a non-HTREE filesystem */
851 #define PR_1_HTREE_SET 0x010047
853 /* INDEX_FL flag set on a non-directory */
854 #define PR_1_HTREE_NODIR 0x010048
856 /* Invalid root node in HTREE directory */
857 #define PR_1_HTREE_BADROOT 0x010049
859 /* Unsupported hash version in HTREE directory */
860 #define PR_1_HTREE_HASHV 0x01004A
862 /* Incompatible flag in HTREE root node */
863 #define PR_1_HTREE_INCOMPAT 0x01004B
866 #define PR_1_HTREE_DEPTH 0x01004C
868 /* Bad block has indirect block that conflicts with filesystem block */
869 #define PR_1_BB_FS_BLOCK 0x01004D
871 /* Resize inode failed */
872 #define PR_1_RESIZE_INODE_CREATE 0x01004E
874 /* inode->i_size is too long */
875 #define PR_1_EXTRA_ISIZE 0x01004F
877 /* attribute name is too long */
878 #define PR_1_ATTR_NAME_LEN 0x010050
880 /* wrong EA value offset */
881 #define PR_1_ATTR_VALUE_OFFSET 0x010051
883 /* wrong EA blocknumber */
884 #define PR_1_ATTR_VALUE_BLOCK 0x010052
886 /* wrong EA value size */
887 #define PR_1_ATTR_VALUE_SIZE 0x010053
889 /* wrong EA hash value */
890 #define PR_1_ATTR_HASH 0x010054
896 /* Pass 1B: Rescan for duplicate/bad blocks */
897 #define PR_1B_PASS_HEADER 0x011000
899 /* Duplicate/bad block(s) header */
900 #define PR_1B_DUP_BLOCK_HEADER 0x011001
902 /* Duplicate/bad block(s) in inode */
903 #define PR_1B_DUP_BLOCK 0x011002
905 /* Duplicate/bad block(s) end */
906 #define PR_1B_DUP_BLOCK_END 0x011003
908 /* Error while scanning inodes */
909 #define PR_1B_ISCAN_ERROR 0x011004
911 /* Error allocating inode bitmap */
912 #define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005
914 /* Error while iterating over blocks */
915 #define PR_1B_BLOCK_ITERATE 0x0110006
917 /* Error adjusting EA refcount */
918 #define PR_1B_ADJ_EA_REFCOUNT 0x0110007
921 /* Pass 1C: Scan directories for inodes with dup blocks. */
922 #define PR_1C_PASS_HEADER 0x012000
925 /* Pass 1D: Reconciling duplicate blocks */
926 #define PR_1D_PASS_HEADER 0x013000
928 /* File has duplicate blocks */
929 #define PR_1D_DUP_FILE 0x013001
931 /* List of files sharing duplicate blocks */
932 #define PR_1D_DUP_FILE_LIST 0x013002
934 /* File sharing blocks with filesystem metadata */
935 #define PR_1D_SHARE_METADATA 0x013003
937 /* Report of how many duplicate/bad inodes */
938 #define PR_1D_NUM_DUP_INODES 0x013004
940 /* Duplicated blocks already reassigned or cloned. */
941 #define PR_1D_DUP_BLOCKS_DEALT 0x013005
943 /* Clone duplicate/bad blocks? */
944 #define PR_1D_CLONE_QUESTION 0x013006
947 #define PR_1D_DELETE_QUESTION 0x013007
949 /* Couldn't clone file (error) */
950 #define PR_1D_CLONE_ERROR 0x013008
956 /* Pass 2: Checking directory structure */
957 #define PR_2_PASS_HEADER 0x020000
959 /* Bad inode number for '.' */
960 #define PR_2_BAD_INODE_DOT 0x020001
962 /* Directory entry has bad inode number */
963 #define PR_2_BAD_INO 0x020002
965 /* Directory entry has deleted or unused inode */
966 #define PR_2_UNUSED_INODE 0x020003
968 /* Directry entry is link to '.' */
969 #define PR_2_LINK_DOT 0x020004
971 /* Directory entry points to inode now located in a bad block */
972 #define PR_2_BB_INODE 0x020005
974 /* Directory entry contains a link to a directory */
975 #define PR_2_LINK_DIR 0x020006
977 /* Directory entry contains a link to the root directry */
978 #define PR_2_LINK_ROOT 0x020007
980 /* Directory entry has illegal characters in its name */
981 #define PR_2_BAD_NAME 0x020008
983 /* Missing '.' in directory inode */
984 #define PR_2_MISSING_DOT 0x020009
986 /* Missing '..' in directory inode */
987 #define PR_2_MISSING_DOT_DOT 0x02000A
989 /* First entry in directory inode doesn't contain '.' */
990 #define PR_2_1ST_NOT_DOT 0x02000B
992 /* Second entry in directory inode doesn't contain '..' */
993 #define PR_2_2ND_NOT_DOT_DOT 0x02000C
995 /* i_faddr should be zero */
996 #define PR_2_FADDR_ZERO 0x02000D
998 /* i_file_acl should be zero */
999 #define PR_2_FILE_ACL_ZERO 0x02000E
1001 /* i_dir_acl should be zero */
1002 #define PR_2_DIR_ACL_ZERO 0x02000F
1004 /* i_frag should be zero */
1005 #define PR_2_FRAG_ZERO 0x020010
1007 /* i_fsize should be zero */
1008 #define PR_2_FSIZE_ZERO 0x020011
1010 /* inode has bad mode */
1011 #define PR_2_BAD_MODE 0x020012
1013 /* directory corrupted */
1014 #define PR_2_DIR_CORRUPTED 0x020013
1016 /* filename too long */
1017 #define PR_2_FILENAME_LONG 0x020014
1019 /* Directory inode has a missing block (hole) */
1020 #define PR_2_DIRECTORY_HOLE 0x020015
1022 /* '.' is not NULL terminated */
1023 #define PR_2_DOT_NULL_TERM 0x020016
1025 /* '..' is not NULL terminated */
1026 #define PR_2_DOT_DOT_NULL_TERM 0x020017
1028 /* Illegal character device in inode */
1029 #define PR_2_BAD_CHAR_DEV 0x020018
1031 /* Illegal block device in inode */
1032 #define PR_2_BAD_BLOCK_DEV 0x020019
1034 /* Duplicate '.' entry */
1035 #define PR_2_DUP_DOT 0x02001A
1037 /* Duplicate '..' entry */
1038 #define PR_2_DUP_DOT_DOT 0x02001B
1040 /* Internal error: couldn't find dir_info */
1041 #define PR_2_NO_DIRINFO 0x02001C
1043 /* Final rec_len is wrong */
1044 #define PR_2_FINAL_RECLEN 0x02001D
1046 /* Error allocating icount structure */
1047 #define PR_2_ALLOCATE_ICOUNT 0x02001E
1049 /* Error iterating over directory blocks */
1050 #define PR_2_DBLIST_ITERATE 0x02001F
1052 /* Error reading directory block */
1053 #define PR_2_READ_DIRBLOCK 0x020020
1055 /* Error writing directory block */
1056 #define PR_2_WRITE_DIRBLOCK 0x020021
1058 /* Error allocating new directory block */
1059 #define PR_2_ALLOC_DIRBOCK 0x020022
1061 /* Error deallocating inode */
1062 #define PR_2_DEALLOC_INODE 0x020023
1064 /* Directory entry for '.' is big. Split? */
1065 #define PR_2_SPLIT_DOT 0x020024
1068 #define PR_2_BAD_FIFO 0x020025
1070 /* Illegal socket */
1071 #define PR_2_BAD_SOCKET 0x020026
1073 /* Directory filetype not set */
1074 #define PR_2_SET_FILETYPE 0x020027
1076 /* Directory filetype incorrect */
1077 #define PR_2_BAD_FILETYPE 0x020028
1079 /* Directory filetype set when it shouldn't be */
1080 #define PR_2_CLEAR_FILETYPE 0x020029
1082 /* Directory filename can't be zero-length */
1083 #define PR_2_NULL_NAME 0x020030
1085 /* Invalid symlink */
1086 #define PR_2_INVALID_SYMLINK 0x020031
1088 /* i_file_acl (extended attribute) is bad */
1089 #define PR_2_FILE_ACL_BAD 0x020032
1091 /* Filesystem contains large files, but has no such flag in sb */
1092 #define PR_2_FEATURE_LARGE_FILES 0x020033
1094 /* Node in HTREE directory not referenced */
1095 #define PR_2_HTREE_NOTREF 0x020034
1097 /* Node in HTREE directory referenced twice */
1098 #define PR_2_HTREE_DUPREF 0x020035
1100 /* Node in HTREE directory has bad min hash */
1101 #define PR_2_HTREE_MIN_HASH 0x020036
1103 /* Node in HTREE directory has bad max hash */
1104 #define PR_2_HTREE_MAX_HASH 0x020037
1106 /* Clear invalid HTREE directory */
1107 #define PR_2_HTREE_CLEAR 0x020038
1109 /* Clear the htree flag forcibly */
1110 /* #define PR_2_HTREE_FCLR 0x020039 */
1112 /* Bad block in htree interior node */
1113 #define PR_2_HTREE_BADBLK 0x02003A
1115 /* Error adjusting EA refcount */
1116 #define PR_2_ADJ_EA_REFCOUNT 0x02003B
1118 /* Invalid HTREE root node */
1119 #define PR_2_HTREE_BAD_ROOT 0x02003C
1121 /* Invalid HTREE limit */
1122 #define PR_2_HTREE_BAD_LIMIT 0x02003D
1124 /* Invalid HTREE count */
1125 #define PR_2_HTREE_BAD_COUNT 0x02003E
1127 /* HTREE interior node has out-of-order hashes in table */
1128 #define PR_2_HTREE_HASH_ORDER 0x02003F
1130 /* Node in HTREE directory has bad depth */
1131 #define PR_2_HTREE_BAD_DEPTH 0x020040
1133 /* Duplicate directory entry found */
1134 #define PR_2_DUPLICATE_DIRENT 0x020041
1136 /* Non-unique filename found */
1137 #define PR_2_NON_UNIQUE_FILE 0x020042
1139 /* Duplicate directory entry found */
1140 #define PR_2_REPORT_DUP_DIRENT 0x020043
1146 /* Pass 3: Checking directory connectivity */
1147 #define PR_3_PASS_HEADER 0x030000
1149 /* Root inode not allocated */
1150 #define PR_3_NO_ROOT_INODE 0x030001
1152 /* No room in lost+found */
1153 #define PR_3_EXPAND_LF_DIR 0x030002
1155 /* Unconnected directory inode */
1156 #define PR_3_UNCONNECTED_DIR 0x030003
1158 /* /lost+found not found */
1159 #define PR_3_NO_LF_DIR 0x030004
1161 /* .. entry is incorrect */
1162 #define PR_3_BAD_DOT_DOT 0x030005
1164 /* Bad or non-existent /lost+found. Cannot reconnect */
1165 #define PR_3_NO_LPF 0x030006
1167 /* Could not expand /lost+found */
1168 #define PR_3_CANT_EXPAND_LPF 0x030007
1170 /* Could not reconnect inode */
1171 #define PR_3_CANT_RECONNECT 0x030008
1173 /* Error while trying to find /lost+found */
1174 #define PR_3_ERR_FIND_LPF 0x030009
1176 /* Error in ext2fs_new_block while creating /lost+found */
1177 #define PR_3_ERR_LPF_NEW_BLOCK 0x03000A
1179 /* Error in ext2fs_new_inode while creating /lost+found */
1180 #define PR_3_ERR_LPF_NEW_INODE 0x03000B
1182 /* Error in ext2fs_new_dir_block while creating /lost+found */
1183 #define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C
1185 /* Error while writing directory block for /lost+found */
1186 #define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D
1188 /* Error while adjusting inode count */
1189 #define PR_3_ADJUST_INODE 0x03000E
1191 /* Couldn't fix parent directory -- error */
1192 #define PR_3_FIX_PARENT_ERR 0x03000F
1194 /* Couldn't fix parent directory -- couldn't find it */
1195 #define PR_3_FIX_PARENT_NOFIND 0x030010
1197 /* Error allocating inode bitmap */
1198 #define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011
1200 /* Error creating root directory */
1201 #define PR_3_CREATE_ROOT_ERROR 0x030012
1203 /* Error creating lost and found directory */
1204 #define PR_3_CREATE_LPF_ERROR 0x030013
1206 /* Root inode is not directory; aborting */
1207 #define PR_3_ROOT_NOT_DIR_ABORT 0x030014
1209 /* Cannot proceed without a root inode. */
1210 #define PR_3_NO_ROOT_INODE_ABORT 0x030015
1212 /* Internal error: couldn't find dir_info */
1213 #define PR_3_NO_DIRINFO 0x030016
1215 /* Lost+found is not a directory */
1216 #define PR_3_LPF_NOTDIR 0x030017
1219 * Pass 3a --- rehashing diretories
1221 /* Pass 3a: Reindexing directories */
1222 #define PR_3A_PASS_HEADER 0x031000
1224 /* Error iterating over directories */
1225 #define PR_3A_OPTIMIZE_ITER 0x031001
1227 /* Error rehash directory */
1228 #define PR_3A_OPTIMIZE_DIR_ERR 0x031002
1230 /* Rehashing dir header */
1231 #define PR_3A_OPTIMIZE_DIR_HEADER 0x031003
1233 /* Rehashing directory %d */
1234 #define PR_3A_OPTIMIZE_DIR 0x031004
1236 /* Rehashing dir end */
1237 #define PR_3A_OPTIMIZE_DIR_END 0x031005
1243 /* Pass 4: Checking reference counts */
1244 #define PR_4_PASS_HEADER 0x040000
1246 /* Unattached zero-length inode */
1247 #define PR_4_ZERO_LEN_INODE 0x040001
1249 /* Unattached inode */
1250 #define PR_4_UNATTACHED_INODE 0x040002
1252 /* Inode ref count wrong */
1253 #define PR_4_BAD_REF_COUNT 0x040003
1255 /* Inconsistent inode count information cached */
1256 #define PR_4_INCONSISTENT_COUNT 0x040004
1262 /* Pass 5: Checking group summary information */
1263 #define PR_5_PASS_HEADER 0x050000
1265 /* Padding at end of inode bitmap is not set. */
1266 #define PR_5_INODE_BMAP_PADDING 0x050001
1268 /* Padding at end of block bitmap is not set. */
1269 #define PR_5_BLOCK_BMAP_PADDING 0x050002
1271 /* Block bitmap differences header */
1272 #define PR_5_BLOCK_BITMAP_HEADER 0x050003
1274 /* Block not used, but marked in bitmap */
1275 #define PR_5_BLOCK_UNUSED 0x050004
1277 /* Block used, but not marked used in bitmap */
1278 #define PR_5_BLOCK_USED 0x050005
1280 /* Block bitmap differences end */
1281 #define PR_5_BLOCK_BITMAP_END 0x050006
1283 /* Inode bitmap differences header */
1284 #define PR_5_INODE_BITMAP_HEADER 0x050007
1286 /* Inode not used, but marked in bitmap */
1287 #define PR_5_INODE_UNUSED 0x050008
1289 /* Inode used, but not marked used in bitmap */
1290 #define PR_5_INODE_USED 0x050009
1292 /* Inode bitmap differences end */
1293 #define PR_5_INODE_BITMAP_END 0x05000A
1295 /* Free inodes count for group wrong */
1296 #define PR_5_FREE_INODE_COUNT_GROUP 0x05000B
1298 /* Directories count for group wrong */
1299 #define PR_5_FREE_DIR_COUNT_GROUP 0x05000C
1301 /* Free inodes count wrong */
1302 #define PR_5_FREE_INODE_COUNT 0x05000D
1304 /* Free blocks count for group wrong */
1305 #define PR_5_FREE_BLOCK_COUNT_GROUP 0x05000E
1307 /* Free blocks count wrong */
1308 #define PR_5_FREE_BLOCK_COUNT 0x05000F
1310 /* Programming error: bitmap endpoints don't match */
1311 #define PR_5_BMAP_ENDPOINTS 0x050010
1313 /* Internal error: fudging end of bitmap */
1314 #define PR_5_FUDGE_BITMAP_ERROR 0x050011
1316 /* Error copying in replacement inode bitmap */
1317 #define PR_5_COPY_IBITMAP_ERROR 0x050012
1319 /* Error copying in replacement block bitmap */
1320 #define PR_5_COPY_BBITMAP_ERROR 0x050013
1322 /* Block range not used, but marked in bitmap */
1323 #define PR_5_BLOCK_RANGE_UNUSED 0x050014
1325 /* Block range used, but not marked used in bitmap */
1326 #define PR_5_BLOCK_RANGE_USED 0x050015
1328 /* Inode range not used, but marked in bitmap */
1329 #define PR_5_INODE_RANGE_UNUSED 0x050016
1331 /* Inode rangeused, but not marked used in bitmap */
1332 #define PR_5_INODE_RANGE_USED 0x050017
1335 * Function declarations
1337 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
1338 static int end_problem_latch(e2fsck_t ctx, int mask);
1339 static int set_latch_flags(int mask, int setflags, int clearflags);
1340 static void clear_problem_context(struct problem_context *ctx);
1343 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
1344 struct problem_context *pctx, int first);
1347 * Dictionary Abstract Data Type
1348 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
1350 * Free Software License:
1352 * All rights are reserved by the author, with the following exceptions:
1353 * Permission is granted to freely reproduce and distribute this software,
1354 * possibly in exchange for a fee, provided that this copyright notice appears
1355 * intact. Permission is also granted to adapt this software to produce
1356 * derivative works, as long as the modified versions carry this copyright
1357 * notice and additional notices stating that the work has been modified.
1358 * This source code may be translated into executable form and incorporated
1359 * into proprietary software; there is no requirement for such software to
1360 * contain a copyright notice related to this source.
1362 * $Id: dict.h,v 1.22.2.6 2000/11/13 01:36:44 kaz Exp $
1363 * $Name: kazlib_1_20 $
1370 * Blurb for inclusion into C++ translation units
1373 typedef unsigned long dictcount_t;
1374 #define DICTCOUNT_T_MAX ULONG_MAX
1377 * The dictionary is implemented as a red-black tree
1380 typedef enum { dnode_red, dnode_black } dnode_color_t;
1382 typedef struct dnode_t {
1383 struct dnode_t *dict_left;
1384 struct dnode_t *dict_right;
1385 struct dnode_t *dict_parent;
1386 dnode_color_t dict_color;
1387 const void *dict_key;
1391 typedef int (*dict_comp_t)(const void *, const void *);
1392 typedef dnode_t *(*dnode_alloc_t)(void *);
1393 typedef void (*dnode_free_t)(dnode_t *, void *);
1395 typedef struct dict_t {
1396 dnode_t dict_nilnode;
1397 dictcount_t dict_nodecount;
1398 dictcount_t dict_maxcount;
1399 dict_comp_t dict_compare;
1400 dnode_alloc_t dict_allocnode;
1401 dnode_free_t dict_freenode;
1406 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
1408 typedef struct dict_load_t {
1409 dict_t *dict_dictptr;
1410 dnode_t dict_nilnode;
1413 static void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
1414 static void dict_free_nodes(dict_t *);
1415 static dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t);
1416 static dnode_t *dict_lookup(dict_t *, const void *);
1417 static void dict_insert(dict_t *, dnode_t *, const void *);
1418 static int dict_alloc_insert(dict_t *, const void *, void *);
1419 static dnode_t *dict_first(dict_t *);
1420 static dnode_t *dict_next(dict_t *, dnode_t *);
1421 static dictcount_t dict_count(dict_t *);
1422 static dnode_t *dnode_init(dnode_t *, void *);
1423 static void *dnode_get(dnode_t *);
1424 static const void *dnode_getkey(dnode_t *);
1426 #define dict_count(D) ((D)->dict_nodecount)
1427 #define dnode_get(N) ((N)->dict_data)
1428 #define dnode_getkey(N) ((N)->dict_key)
1433 * Compatibility header file for e2fsck which should be included
1434 * instead of linux/jfs.h
1436 * Copyright (C) 2000 Stephen C. Tweedie
1440 * Pull in the definition of the e2fsck context structure
1444 struct buffer_head {
1458 struct ext2_inode i_ext2;
1467 #define K_DEV_JOURNAL 2
1469 typedef struct kdev_s *kdev_t;
1471 #define lock_buffer(bh) do {} while(0)
1472 #define unlock_buffer(bh) do {} while(0)
1473 #define buffer_req(bh) 1
1474 #define do_readahead(journal, start) do {} while(0)
1476 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
1482 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
1483 #define kmem_cache_free(cache,obj) free(obj)
1484 #define kmem_cache_create(name,len,a,b,c,d) do_cache_create(len)
1485 #define kmem_cache_destroy(cache) do_cache_destroy(cache)
1486 #define kmalloc(len,flags) malloc(len)
1487 #define kfree(p) free(p)
1490 * We use the standard libext2fs portability tricks for inline
1494 static _INLINE_ kmem_cache_t * do_cache_create(int len)
1496 kmem_cache_t *new_cache;
1497 new_cache = malloc(sizeof(*new_cache));
1499 new_cache->object_length = len;
1503 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
1509 * Now pull in the real linux/jfs.h definitions.
1511 #include "ext2fs/kernel-jbd.h"
1514 * Kernel compatibility functions are defined in journal.c
1516 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys);
1517 static struct buffer_head *getblk(kdev_t ctx, blk_t blocknr, int blocksize);
1518 static void sync_blockdev(kdev_t kdev);
1519 static void ll_rw_block(int rw, int dummy, struct buffer_head *bh[]);
1520 static void mark_buffer_dirty(struct buffer_head *bh);
1521 static void mark_buffer_uptodate(struct buffer_head *bh, int val);
1522 static void brelse(struct buffer_head *bh);
1523 static int buffer_uptodate(struct buffer_head *bh);
1524 static void wait_on_buffer(struct buffer_head *bh);
1527 * Define newer 2.5 interfaces
1529 #define __getblk(dev, blocknr, blocksize) getblk(dev, blocknr, blocksize)
1530 #define set_buffer_uptodate(bh) mark_buffer_uptodate(bh, 1)
1533 * badblocks.c --- replace/append bad blocks to the bad block inode
1535 * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
1536 * redistributed under the terms of the GNU Public License.
1539 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
1543 static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk)
1545 printf(_("Bad block %u out of range; ignored.\n"), blk);
1549 void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
1550 int replace_bad_blocks)
1552 ext2_filsys fs = ctx->fs;
1554 badblocks_list bb_list = 0;
1558 e2fsck_read_bitmaps(ctx);
1561 * Make sure the bad block inode is sane. If there are any
1562 * illegal blocks, clear them.
1564 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
1565 check_bb_inode_blocks, 0);
1567 com_err("ext2fs_block_iterate", retval,
1568 _("while sanity checking the bad blocks inode"));
1573 * If we're appending to the bad blocks inode, read in the
1574 * current bad blocks.
1576 if (!replace_bad_blocks) {
1577 retval = ext2fs_read_bb_inode(fs, &bb_list);
1579 com_err("ext2fs_read_bb_inode", retval,
1580 _("while reading the bad blocks inode"));
1586 * Now read in the bad blocks from the file; if
1587 * bad_blocks_file is null, then try to run the badblocks
1590 if (bad_blocks_file) {
1591 f = fopen(bad_blocks_file, "r");
1593 com_err("read_bad_blocks_file", errno,
1594 _("while trying to open %s"), bad_blocks_file);
1598 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
1599 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
1600 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
1601 fs->device_name, fs->super->s_blocks_count);
1602 f = popen(buf, "r");
1604 com_err("read_bad_blocks_file", errno,
1605 _("while trying popen '%s'"), buf);
1609 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
1610 if (bad_blocks_file)
1615 com_err("ext2fs_read_bb_FILE", retval,
1616 _("while reading in list of bad blocks from file"));
1621 * Finally, update the bad blocks from the bad_block_map
1623 retval = ext2fs_update_bb_inode(fs, bb_list);
1625 com_err("ext2fs_update_bb_inode", retval,
1626 _("while updating bad block inode"));
1630 ext2fs_badblocks_list_free(bb_list);
1634 ctx->flags |= E2F_FLAG_ABORT;
1639 static int check_bb_inode_blocks(ext2_filsys fs,
1641 int blockcnt EXT2FS_ATTR((unused)),
1642 void *priv_data EXT2FS_ATTR((unused)))
1648 * If the block number is outrageous, clear it and ignore it.
1650 if (*block_nr >= fs->super->s_blocks_count ||
1651 *block_nr < fs->super->s_first_data_block) {
1652 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
1654 return BLOCK_CHANGED;
1661 * Dictionary Abstract Data Type
1662 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
1664 * Free Software License:
1666 * All rights are reserved by the author, with the following exceptions:
1667 * Permission is granted to freely reproduce and distribute this software,
1668 * possibly in exchange for a fee, provided that this copyright notice appears
1669 * intact. Permission is also granted to adapt this software to produce
1670 * derivative works, as long as the modified versions carry this copyright
1671 * notice and additional notices stating that the work has been modified.
1672 * This source code may be translated into executable form and incorporated
1673 * into proprietary software; there is no requirement for such software to
1674 * contain a copyright notice related to this source.
1676 * $Id: dict.c,v 1.40.2.7 2000/11/13 01:36:44 kaz Exp $
1677 * $Name: kazlib_1_20 $
1682 * These macros provide short convenient names for structure members,
1683 * which are embellished with dict_ prefixes so that they are
1684 * properly confined to the documented namespace. It's legal for a
1685 * program which uses dict to define, for instance, a macro called ``parent''.
1686 * Such a macro would interfere with the dnode_t struct definition.
1687 * In general, highly portable and reusable C modules which expose their
1688 * structures need to confine structure member names to well-defined spaces.
1689 * The resulting identifiers aren't necessarily convenient to use, nor
1690 * readable, in the implementation, however!
1693 #define left dict_left
1694 #define right dict_right
1695 #define parent dict_parent
1696 #define color dict_color
1697 #define key dict_key
1698 #define data dict_data
1700 #define nilnode dict_nilnode
1701 #define nodecount dict_nodecount
1702 #define maxcount dict_maxcount
1703 #define compare dict_compare
1704 #define allocnode dict_allocnode
1705 #define freenode dict_freenode
1706 #define context dict_context
1707 #define dupes dict_dupes
1709 #define dictptr dict_dictptr
1711 #define dict_root(D) ((D)->nilnode.left)
1712 #define dict_nil(D) (&(D)->nilnode)
1713 #define DICT_DEPTH_MAX 64
1715 static dnode_t *dnode_alloc(void *context);
1716 static void dnode_free(dnode_t *node, void *context);
1719 * Perform a ``left rotation'' adjustment on the tree. The given node P and
1720 * its right child C are rearranged so that the P instead becomes the left
1721 * child of C. The left subtree of C is inherited as the new right subtree
1722 * for P. The ordering of the keys within the tree is thus preserved.
1725 static void rotate_left(dnode_t *upper)
1727 dnode_t *lower, *lowleft, *upparent;
1729 lower = upper->right;
1730 upper->right = lowleft = lower->left;
1731 lowleft->parent = upper;
1733 lower->parent = upparent = upper->parent;
1735 /* don't need to check for root node here because root->parent is
1736 the sentinel nil node, and root->parent->left points back to root */
1738 if (upper == upparent->left) {
1739 upparent->left = lower;
1741 assert (upper == upparent->right);
1742 upparent->right = lower;
1745 lower->left = upper;
1746 upper->parent = lower;
1750 * This operation is the ``mirror'' image of rotate_left. It is
1751 * the same procedure, but with left and right interchanged.
1754 static void rotate_right(dnode_t *upper)
1756 dnode_t *lower, *lowright, *upparent;
1758 lower = upper->left;
1759 upper->left = lowright = lower->right;
1760 lowright->parent = upper;
1762 lower->parent = upparent = upper->parent;
1764 if (upper == upparent->right) {
1765 upparent->right = lower;
1767 assert (upper == upparent->left);
1768 upparent->left = lower;
1771 lower->right = upper;
1772 upper->parent = lower;
1776 * Do a postorder traversal of the tree rooted at the specified
1777 * node and free everything under it. Used by dict_free().
1780 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
1784 free_nodes(dict, node->left, nil);
1785 free_nodes(dict, node->right, nil);
1786 dict->freenode(node, dict->context);
1790 * Verify that the tree contains the given node. This is done by
1791 * traversing all of the nodes and comparing their pointers to the
1792 * given pointer. Returns 1 if the node is found, otherwise
1793 * returns zero. It is intended for debugging purposes.
1796 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
1800 || verify_dict_has_node(nil, root->left, node)
1801 || verify_dict_has_node(nil, root->right, node);
1808 * Select a different set of node allocator routines.
1811 void dict_set_allocator(dict_t *dict, dnode_alloc_t al,
1812 dnode_free_t fr, void *context)
1814 assert (dict_count(dict) == 0);
1815 assert ((al == NULL && fr == NULL) || (al != NULL && fr != NULL));
1817 dict->allocnode = al ? al : dnode_alloc;
1818 dict->freenode = fr ? fr : dnode_free;
1819 dict->context = context;
1823 * Free all the nodes in the dictionary by using the dictionary's
1824 * installed free routine. The dictionary is emptied.
1827 void dict_free_nodes(dict_t *dict)
1829 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
1830 free_nodes(dict, root, nil);
1831 dict->nodecount = 0;
1832 dict->nilnode.left = &dict->nilnode;
1833 dict->nilnode.right = &dict->nilnode;
1837 * Initialize a user-supplied dictionary object.
1840 dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
1842 dict->compare = comp;
1843 dict->allocnode = dnode_alloc;
1844 dict->freenode = dnode_free;
1845 dict->context = NULL;
1846 dict->nodecount = 0;
1847 dict->maxcount = maxcount;
1848 dict->nilnode.left = &dict->nilnode;
1849 dict->nilnode.right = &dict->nilnode;
1850 dict->nilnode.parent = &dict->nilnode;
1851 dict->nilnode.color = dnode_black;
1857 * Locate a node in the dictionary having the given key.
1858 * If the node is not found, a null a pointer is returned (rather than
1859 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
1860 * located node is returned.
1863 dnode_t *dict_lookup(dict_t *dict, const void *key)
1865 dnode_t *root = dict_root(dict);
1866 dnode_t *nil = dict_nil(dict);
1870 /* simple binary search adapted for trees that contain duplicate keys */
1872 while (root != nil) {
1873 result = dict->compare(key, root->key);
1876 else if (result > 0)
1879 if (!dict->dupes) { /* no duplicates, return match */
1881 } else { /* could be dupes, find leftmost one */
1885 while (root != nil && dict->compare(key, root->key))
1887 } while (root != nil);
1897 * Insert a node into the dictionary. The node should have been
1898 * initialized with a data field. All other fields are ignored.
1899 * The behavior is undefined if the user attempts to insert into
1900 * a dictionary that is already full (for which the dict_isfull()
1901 * function returns true).
1904 void dict_insert(dict_t *dict, dnode_t *node, const void *key)
1906 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
1907 dnode_t *parent = nil, *uncle, *grandpa;
1912 /* basic binary tree insert */
1914 while (where != nil) {
1916 result = dict->compare(key, where->key);
1917 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
1918 assert (dict->dupes || result != 0);
1920 where = where->left;
1922 where = where->right;
1925 assert (where == nil);
1928 parent->left = node;
1930 parent->right = node;
1932 node->parent = parent;
1938 /* red black adjustments */
1940 node->color = dnode_red;
1942 while (parent->color == dnode_red) {
1943 grandpa = parent->parent;
1944 if (parent == grandpa->left) {
1945 uncle = grandpa->right;
1946 if (uncle->color == dnode_red) { /* red parent, red uncle */
1947 parent->color = dnode_black;
1948 uncle->color = dnode_black;
1949 grandpa->color = dnode_red;
1951 parent = grandpa->parent;
1952 } else { /* red parent, black uncle */
1953 if (node == parent->right) {
1954 rotate_left(parent);
1956 assert (grandpa == parent->parent);
1957 /* rotation between parent and child preserves grandpa */
1959 parent->color = dnode_black;
1960 grandpa->color = dnode_red;
1961 rotate_right(grandpa);
1964 } else { /* symmetric cases: parent == parent->parent->right */
1965 uncle = grandpa->left;
1966 if (uncle->color == dnode_red) {
1967 parent->color = dnode_black;
1968 uncle->color = dnode_black;
1969 grandpa->color = dnode_red;
1971 parent = grandpa->parent;
1973 if (node == parent->left) {
1974 rotate_right(parent);
1976 assert (grandpa == parent->parent);
1978 parent->color = dnode_black;
1979 grandpa->color = dnode_red;
1980 rotate_left(grandpa);
1986 dict_root(dict)->color = dnode_black;
1991 * Allocate a node using the dictionary's allocator routine, give it
1995 int dict_alloc_insert(dict_t *dict, const void *key, void *data)
1997 dnode_t *node = dict->allocnode(dict->context);
2000 dnode_init(node, data);
2001 dict_insert(dict, node, key);
2008 * Return the node with the lowest (leftmost) key. If the dictionary is empty
2009 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
2012 dnode_t *dict_first(dict_t *dict)
2014 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
2017 while ((left = root->left) != nil)
2020 return (root == nil) ? NULL : root;
2024 * Return the given node's successor node---the node which has the
2025 * next key in the the left to right ordering. If the node has
2026 * no successor, a null pointer is returned rather than a pointer to
2030 dnode_t *dict_next(dict_t *dict, dnode_t *curr)
2032 dnode_t *nil = dict_nil(dict), *parent, *left;
2034 if (curr->right != nil) {
2036 while ((left = curr->left) != nil)
2041 parent = curr->parent;
2043 while (parent != nil && curr == parent->right) {
2045 parent = curr->parent;
2048 return (parent == nil) ? NULL : parent;
2055 dictcount_t dict_count(dict_t *dict)
2057 return dict->nodecount;
2060 static dnode_t *dnode_alloc(void *context EXT2FS_ATTR((unused)))
2062 return malloc(sizeof *dnode_alloc(NULL));
2065 static void dnode_free(dnode_t *node, void *context EXT2FS_ATTR((unused)))
2070 dnode_t *dnode_init(dnode_t *dnode, void *data)
2073 dnode->parent = NULL;
2075 dnode->right = NULL;
2079 void *dnode_get(dnode_t *dnode)
2084 const void *dnode_getkey(dnode_t *dnode)
2109 * dirinfo.c --- maintains the directory information table for e2fsck.
2111 * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
2112 * under the terms of the GNU Public License.
2116 * This subroutine is called during pass1 to create a directory info
2117 * entry. During pass1, the passed-in parent is 0; it will get filled
2120 void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
2122 struct dir_info *dir;
2124 ext2_ino_t num_dirs;
2126 unsigned long old_size;
2129 printf("add_dir_info for inode %lu...\n", ino);
2131 if (!ctx->dir_info) {
2132 ctx->dir_info_count = 0;
2133 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
2135 num_dirs = 1024; /* Guess */
2136 ctx->dir_info_size = num_dirs + 10;
2137 ctx->dir_info = (struct dir_info *)
2138 e2fsck_allocate_memory(ctx, ctx->dir_info_size
2139 * sizeof (struct dir_info),
2143 if (ctx->dir_info_count >= ctx->dir_info_size) {
2144 old_size = ctx->dir_info_size * sizeof(struct dir_info);
2145 ctx->dir_info_size += 10;
2146 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
2147 sizeof(struct dir_info),
2150 ctx->dir_info_size -= 10;
2156 * Normally, add_dir_info is called with each inode in
2157 * sequential order; but once in a while (like when pass 3
2158 * needs to recreate the root directory or lost+found
2159 * directory) it is called out of order. In those cases, we
2160 * need to move the dir_info entries down to make room, since
2161 * the dir_info array needs to be sorted by inode number for
2162 * get_dir_info()'s sake.
2164 if (ctx->dir_info_count &&
2165 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
2166 for (i = ctx->dir_info_count-1; i > 0; i--)
2167 if (ctx->dir_info[i-1].ino < ino)
2169 dir = &ctx->dir_info[i];
2170 if (dir->ino != ino)
2171 for (j = ctx->dir_info_count++; j > i; j--)
2172 ctx->dir_info[j] = ctx->dir_info[j-1];
2174 dir = &ctx->dir_info[ctx->dir_info_count++];
2177 dir->dotdot = parent;
2178 dir->parent = parent;
2182 * get_dir_info() --- given an inode number, try to find the directory
2183 * information entry for it.
2185 struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2190 high = ctx->dir_info_count-1;
2193 if (ino == ctx->dir_info[low].ino)
2194 return &ctx->dir_info[low];
2195 if (ino == ctx->dir_info[high].ino)
2196 return &ctx->dir_info[high];
2198 while (low < high) {
2200 if (mid == low || mid == high)
2202 if (ino == ctx->dir_info[mid].ino)
2203 return &ctx->dir_info[mid];
2204 if (ino < ctx->dir_info[mid].ino)
2213 * Free the dir_info structure when it isn't needed any more.
2215 void e2fsck_free_dir_info(e2fsck_t ctx)
2217 if (ctx->dir_info) {
2218 ext2fs_free_mem(&ctx->dir_info);
2221 ctx->dir_info_size = 0;
2222 ctx->dir_info_count = 0;
2226 * Return the count of number of directories in the dir_info structure
2228 int e2fsck_get_num_dirinfo(e2fsck_t ctx)
2230 return ctx->dir_info_count;
2234 * A simple interator function
2236 struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
2238 if (*control >= ctx->dir_info_count)
2241 return(ctx->dir_info + (*control)++);
2244 * dirinfo.c --- maintains the directory information table for e2fsck.
2246 * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
2247 * under the terms of the GNU Public License.
2253 * This subroutine is called during pass1 to create a directory info
2254 * entry. During pass1, the passed-in parent is 0; it will get filled
2257 void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
2259 struct dx_dir_info *dir;
2262 unsigned long old_size;
2265 printf("add_dx_dir_info for inode %lu...\n", ino);
2267 if (!ctx->dx_dir_info) {
2268 ctx->dx_dir_info_count = 0;
2269 ctx->dx_dir_info_size = 100; /* Guess */
2270 ctx->dx_dir_info = (struct dx_dir_info *)
2271 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
2272 * sizeof (struct dx_dir_info),
2276 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
2277 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
2278 ctx->dx_dir_info_size += 10;
2279 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
2280 sizeof(struct dx_dir_info),
2283 ctx->dx_dir_info_size -= 10;
2289 * Normally, add_dx_dir_info is called with each inode in
2290 * sequential order; but once in a while (like when pass 3
2291 * needs to recreate the root directory or lost+found
2292 * directory) it is called out of order. In those cases, we
2293 * need to move the dx_dir_info entries down to make room, since
2294 * the dx_dir_info array needs to be sorted by inode number for
2295 * get_dx_dir_info()'s sake.
2297 if (ctx->dx_dir_info_count &&
2298 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
2299 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
2300 if (ctx->dx_dir_info[i-1].ino < ino)
2302 dir = &ctx->dx_dir_info[i];
2303 if (dir->ino != ino)
2304 for (j = ctx->dx_dir_info_count++; j > i; j--)
2305 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
2307 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
2310 dir->numblocks = num_blocks;
2311 dir->hashversion = 0;
2312 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
2313 * sizeof (struct dx_dirblock_info),
2314 "dx_block info array");
2319 * get_dx_dir_info() --- given an inode number, try to find the directory
2320 * information entry for it.
2322 struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2327 high = ctx->dx_dir_info_count-1;
2328 if (!ctx->dx_dir_info)
2330 if (ino == ctx->dx_dir_info[low].ino)
2331 return &ctx->dx_dir_info[low];
2332 if (ino == ctx->dx_dir_info[high].ino)
2333 return &ctx->dx_dir_info[high];
2335 while (low < high) {
2337 if (mid == low || mid == high)
2339 if (ino == ctx->dx_dir_info[mid].ino)
2340 return &ctx->dx_dir_info[mid];
2341 if (ino < ctx->dx_dir_info[mid].ino)
2350 * Free the dx_dir_info structure when it isn't needed any more.
2352 void e2fsck_free_dx_dir_info(e2fsck_t ctx)
2355 struct dx_dir_info *dir;
2357 if (ctx->dx_dir_info) {
2358 dir = ctx->dx_dir_info;
2359 for (i=0; i < ctx->dx_dir_info_count; i++) {
2360 if (dir->dx_block) {
2361 ext2fs_free_mem(&dir->dx_block);
2365 ext2fs_free_mem(&ctx->dx_dir_info);
2366 ctx->dx_dir_info = 0;
2368 ctx->dx_dir_info_size = 0;
2369 ctx->dx_dir_info_count = 0;
2373 * A simple interator function
2375 struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
2377 if (*control >= ctx->dx_dir_info_count)
2380 return(ctx->dx_dir_info + (*control)++);
2383 #endif /* ENABLE_HTREE */
2385 * e2fsck.c - a consistency checker for the new extended file system.
2387 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
2390 * This file may be redistributed under the terms of the GNU Public
2396 * This function allocates an e2fsck context
2398 errcode_t e2fsck_allocate_context(e2fsck_t *ret)
2403 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
2407 memset(context, 0, sizeof(struct e2fsck_struct));
2409 context->process_inode_size = 256;
2410 context->ext_attr_ver = 2;
2417 * This function resets an e2fsck context; it is called when e2fsck
2418 * needs to be restarted.
2420 errcode_t e2fsck_reset_context(e2fsck_t ctx)
2423 ctx->lost_and_found = 0;
2424 ctx->bad_lost_and_found = 0;
2425 if (ctx->inode_used_map) {
2426 ext2fs_free_inode_bitmap(ctx->inode_used_map);
2427 ctx->inode_used_map = 0;
2429 if (ctx->inode_dir_map) {
2430 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
2431 ctx->inode_dir_map = 0;
2433 if (ctx->inode_reg_map) {
2434 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
2435 ctx->inode_reg_map = 0;
2437 if (ctx->block_found_map) {
2438 ext2fs_free_block_bitmap(ctx->block_found_map);
2439 ctx->block_found_map = 0;
2441 if (ctx->inode_link_info) {
2442 ext2fs_free_icount(ctx->inode_link_info);
2443 ctx->inode_link_info = 0;
2445 if (ctx->journal_io) {
2446 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2447 io_channel_close(ctx->journal_io);
2448 ctx->journal_io = 0;
2450 if (ctx->fs && ctx->fs->dblist) {
2451 ext2fs_free_dblist(ctx->fs->dblist);
2452 ctx->fs->dblist = 0;
2454 e2fsck_free_dir_info(ctx);
2456 e2fsck_free_dx_dir_info(ctx);
2458 if (ctx->refcount) {
2459 ea_refcount_free(ctx->refcount);
2462 if (ctx->refcount_extra) {
2463 ea_refcount_free(ctx->refcount_extra);
2464 ctx->refcount_extra = 0;
2466 if (ctx->block_dup_map) {
2467 ext2fs_free_block_bitmap(ctx->block_dup_map);
2468 ctx->block_dup_map = 0;
2470 if (ctx->block_ea_map) {
2471 ext2fs_free_block_bitmap(ctx->block_ea_map);
2472 ctx->block_ea_map = 0;
2474 if (ctx->inode_bb_map) {
2475 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
2476 ctx->inode_bb_map = 0;
2478 if (ctx->inode_bad_map) {
2479 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
2480 ctx->inode_bad_map = 0;
2482 if (ctx->inode_imagic_map) {
2483 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
2484 ctx->inode_imagic_map = 0;
2486 if (ctx->dirs_to_hash) {
2487 ext2fs_u32_list_free(ctx->dirs_to_hash);
2488 ctx->dirs_to_hash = 0;
2492 * Clear the array of invalid meta-data flags
2494 if (ctx->invalid_inode_bitmap_flag) {
2495 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
2496 ctx->invalid_inode_bitmap_flag = 0;
2498 if (ctx->invalid_block_bitmap_flag) {
2499 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
2500 ctx->invalid_block_bitmap_flag = 0;
2502 if (ctx->invalid_inode_table_flag) {
2503 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
2504 ctx->invalid_inode_table_flag = 0;
2507 /* Clear statistic counters */
2508 ctx->fs_directory_count = 0;
2509 ctx->fs_regular_count = 0;
2510 ctx->fs_blockdev_count = 0;
2511 ctx->fs_chardev_count = 0;
2512 ctx->fs_links_count = 0;
2513 ctx->fs_symlinks_count = 0;
2514 ctx->fs_fast_symlinks_count = 0;
2515 ctx->fs_fifo_count = 0;
2516 ctx->fs_total_count = 0;
2517 ctx->fs_badblocks_count = 0;
2518 ctx->fs_sockets_count = 0;
2519 ctx->fs_ind_count = 0;
2520 ctx->fs_dind_count = 0;
2521 ctx->fs_tind_count = 0;
2522 ctx->fs_fragmented = 0;
2523 ctx->large_files = 0;
2525 /* Reset the superblock to the user's requested value */
2526 ctx->superblock = ctx->use_superblock;
2531 void e2fsck_free_context(e2fsck_t ctx)
2536 e2fsck_reset_context(ctx);
2538 blkid_put_cache(ctx->blkid);
2540 ext2fs_free_mem(&ctx);
2544 * This function runs through the e2fsck passes and calls them all,
2545 * returning restart, abort, or cancel as necessary...
2547 typedef void (*pass_t)(e2fsck_t ctx);
2549 static pass_t e2fsck_passes[] = {
2550 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
2553 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
2555 int e2fsck_run(e2fsck_t ctx)
2560 if (setjmp(ctx->abort_loc)) {
2561 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
2562 return (ctx->flags & E2F_FLAG_RUN_RETURN);
2564 ctx->flags |= E2F_FLAG_SETJMP_OK;
2566 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
2567 if (ctx->flags & E2F_FLAG_RUN_RETURN)
2571 (void) (ctx->progress)(ctx, 0, 0, 0);
2573 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
2575 if (ctx->flags & E2F_FLAG_RUN_RETURN)
2576 return (ctx->flags & E2F_FLAG_RUN_RETURN);
2582 * Copyright (C) 2001 Theodore Ts'o. This file may be
2583 * redistributed under the terms of the GNU Public License.
2587 * The strategy we use for keeping track of EA refcounts is as
2588 * follows. We keep a sorted array of first EA blocks and its
2589 * reference counts. Once the refcount has dropped to zero, it is
2590 * removed from the array to save memory space. Once the EA block is
2591 * checked, its bit is set in the block_ea_map bitmap.
2593 struct ea_refcount_el {
2598 struct ea_refcount {
2602 struct ea_refcount_el *list;
2605 void ea_refcount_free(ext2_refcount_t refcount)
2611 ext2fs_free_mem(&refcount->list);
2612 ext2fs_free_mem(&refcount);
2615 errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
2617 ext2_refcount_t refcount;
2621 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
2624 memset(refcount, 0, sizeof(struct ea_refcount));
2628 refcount->size = size;
2629 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
2631 printf("Refcount allocated %d entries, %d bytes.\n",
2632 refcount->size, bytes);
2634 retval = ext2fs_get_mem(bytes, &refcount->list);
2637 memset(refcount->list, 0, bytes);
2639 refcount->count = 0;
2640 refcount->cursor = 0;
2646 ea_refcount_free(refcount);
2651 * collapse_refcount() --- go through the refcount array, and get rid
2652 * of any count == zero entries
2654 static void refcount_collapse(ext2_refcount_t refcount)
2657 struct ea_refcount_el *list;
2659 list = refcount->list;
2660 for (i = 0, j = 0; i < refcount->count; i++) {
2661 if (list[i].ea_count) {
2667 #if defined(DEBUG) || defined(TEST_PROGRAM)
2668 printf("Refcount_collapse: size was %d, now %d\n",
2669 refcount->count, j);
2671 refcount->count = j;
2676 * insert_refcount_el() --- Insert a new entry into the sorted list at a
2677 * specified position.
2679 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
2682 struct ea_refcount_el *el;
2687 if (refcount->count >= refcount->size) {
2688 new_size = refcount->size + 100;
2690 printf("Reallocating refcount %d entries...\n", new_size);
2692 retval = ext2fs_resize_mem((size_t) refcount->size *
2693 sizeof(struct ea_refcount_el),
2695 sizeof(struct ea_refcount_el),
2699 refcount->size = new_size;
2701 num = (int) refcount->count - pos;
2703 return 0; /* should never happen */
2705 memmove(&refcount->list[pos+1], &refcount->list[pos],
2706 sizeof(struct ea_refcount_el) * num);
2709 el = &refcount->list[pos];
2717 * get_refcount_el() --- given an block number, try to find refcount
2718 * information in the sorted list. If the create flag is set,
2719 * and we can't find an entry, create one in the sorted list.
2721 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
2722 blk_t blk, int create)
2726 blk_t lowval, highval;
2728 if (!refcount || !refcount->list)
2732 high = (int) refcount->count-1;
2733 if (create && ((refcount->count == 0) ||
2734 (blk > refcount->list[high].ea_blk))) {
2735 if (refcount->count >= refcount->size)
2736 refcount_collapse(refcount);
2738 return insert_refcount_el(refcount, blk,
2739 (unsigned) refcount->count);
2741 if (refcount->count == 0)
2744 if (refcount->cursor >= refcount->count)
2745 refcount->cursor = 0;
2746 if (blk == refcount->list[refcount->cursor].ea_blk)
2747 return &refcount->list[refcount->cursor++];
2749 printf("Non-cursor get_refcount_el: %u\n", blk);
2751 while (low <= high) {
2758 /* Interpolate for efficiency */
2759 lowval = refcount->list[low].ea_blk;
2760 highval = refcount->list[high].ea_blk;
2764 else if (blk > highval)
2767 range = ((float) (blk - lowval)) /
2769 mid = low + ((int) (range * (high-low)));
2772 if (blk == refcount->list[mid].ea_blk) {
2773 refcount->cursor = mid+1;
2774 return &refcount->list[mid];
2776 if (blk < refcount->list[mid].ea_blk)
2782 * If we need to create a new entry, it should be right at
2783 * low (where high will be left at low-1).
2786 if (refcount->count >= refcount->size) {
2787 refcount_collapse(refcount);
2788 if (refcount->count < refcount->size)
2791 return insert_refcount_el(refcount, blk, low);
2796 errcode_t ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
2798 struct ea_refcount_el *el;
2800 el = get_refcount_el(refcount, blk, 1);
2802 return EXT2_ET_NO_MEMORY;
2806 *ret = el->ea_count;
2810 errcode_t ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
2812 struct ea_refcount_el *el;
2814 el = get_refcount_el(refcount, blk, 0);
2815 if (!el || el->ea_count == 0)
2816 return EXT2_ET_INVALID_ARGUMENT;
2821 *ret = el->ea_count;
2825 errcode_t ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
2827 struct ea_refcount_el *el;
2830 * Get the refcount element
2832 el = get_refcount_el(refcount, blk, count ? 1 : 0);
2834 return count ? EXT2_ET_NO_MEMORY : 0;
2835 el->ea_count = count;
2839 void ea_refcount_intr_begin(ext2_refcount_t refcount)
2841 refcount->cursor = 0;
2845 blk_t ea_refcount_intr_next(ext2_refcount_t refcount,
2848 struct ea_refcount_el *list;
2851 if (refcount->cursor >= refcount->count)
2853 list = refcount->list;
2854 if (list[refcount->cursor].ea_count) {
2856 *ret = list[refcount->cursor].ea_count;
2857 return list[refcount->cursor++].ea_blk;
2865 * ehandler.c --- handle bad block errors which come up during the
2866 * course of an e2fsck session.
2868 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
2869 * under the terms of the GNU Public License.
2873 static const char *operation;
2875 static errcode_t e2fsck_handle_read_error(io_channel channel,
2876 unsigned long block,
2879 size_t size EXT2FS_ATTR((unused)),
2880 int actual EXT2FS_ATTR((unused)),
2885 ext2_filsys fs = (ext2_filsys) channel->app_data;
2888 ctx = (e2fsck_t) fs->priv_data;
2891 * If more than one block was read, try reading each block
2892 * separately. We could use the actual bytes read to figure
2893 * out where to start, but we don't bother.
2897 for (i=0; i < count; i++, p += channel->block_size, block++) {
2898 error = io_channel_read_blk(channel, block,
2906 printf(_("Error reading block %lu (%s) while %s. "), block,
2907 error_message(error), operation);
2909 printf(_("Error reading block %lu (%s). "), block,
2910 error_message(error));
2912 if (ask(ctx, _("Ignore error"), 1)) {
2913 if (ask(ctx, _("Force rewrite"), 1))
2914 io_channel_write_blk(channel, block, 1, data);
2921 static errcode_t e2fsck_handle_write_error(io_channel channel,
2922 unsigned long block,
2925 size_t size EXT2FS_ATTR((unused)),
2926 int actual EXT2FS_ATTR((unused)),
2931 ext2_filsys fs = (ext2_filsys) channel->app_data;
2934 ctx = (e2fsck_t) fs->priv_data;
2937 * If more than one block was written, try writing each block
2938 * separately. We could use the actual bytes read to figure
2939 * out where to start, but we don't bother.
2942 p = (const char *) data;
2943 for (i=0; i < count; i++, p += channel->block_size, block++) {
2944 error = io_channel_write_blk(channel, block,
2953 printf(_("Error writing block %lu (%s) while %s. "), block,
2954 error_message(error), operation);
2956 printf(_("Error writing block %lu (%s). "), block,
2957 error_message(error));
2959 if (ask(ctx, _("Ignore error"), 1))
2965 const char *ehandler_operation(const char *op)
2967 const char *ret = operation;
2973 void ehandler_init(io_channel channel)
2975 channel->read_error = e2fsck_handle_read_error;
2976 channel->write_error = e2fsck_handle_write_error;
2979 * journal.c --- code for handling the "ext3" journal
2981 * Copyright (C) 2000 Andreas Dilger
2982 * Copyright (C) 2000 Theodore Ts'o
2984 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
2985 * Copyright (C) 1999 Red Hat Software
2987 * This file may be redistributed under the terms of the
2988 * GNU General Public License version 2 or at your discretion
2989 * any later version.
2992 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
2995 #ifdef __CONFIG_JBD_DEBUG__E2FS /* Enabled by configure --enable-jfs-debug */
2996 static int bh_count = 0;
3000 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
3001 * This creates a larger static binary, and a smaller binary using
3002 * shared libraries. It's also probably slightly less CPU-efficient,
3003 * which is why it's not on by default. But, it's a good way of
3004 * testing the functions in inode_io.c and fileio.c.
3008 /* Kernel compatibility functions for handling the journal. These allow us
3009 * to use the recovery.c file virtually unchanged from the kernel, so we
3010 * don't have to do much to keep kernel and user recovery in sync.
3012 int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
3018 struct inode *inode = journal->j_inode;
3027 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
3028 &inode->i_ext2, NULL, 0, block, &pblk);
3034 struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
3036 struct buffer_head *bh;
3038 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
3042 jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n",
3043 (unsigned long) blocknr, blocksize, ++bh_count);
3045 bh->b_ctx = kdev->k_ctx;
3046 if (kdev->k_dev == K_DEV_FS)
3047 bh->b_io = kdev->k_ctx->fs->io;
3049 bh->b_io = kdev->k_ctx->journal_io;
3050 bh->b_size = blocksize;
3051 bh->b_blocknr = blocknr;
3056 void sync_blockdev(kdev_t kdev)
3060 if (kdev->k_dev == K_DEV_FS)
3061 io = kdev->k_ctx->fs->io;
3063 io = kdev->k_ctx->journal_io;
3065 io_channel_flush(io);
3068 void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
3071 struct buffer_head *bh;
3073 for (; nr > 0; --nr) {
3075 if (rw == READ && !bh->b_uptodate) {
3076 jfs_debug(3, "reading block %lu/%p\n",
3077 (unsigned long) bh->b_blocknr, (void *) bh);
3078 retval = io_channel_read_blk(bh->b_io,
3082 com_err(bh->b_ctx->device_name, retval,
3083 "while reading block %lu\n",
3084 (unsigned long) bh->b_blocknr);
3089 } else if (rw == WRITE && bh->b_dirty) {
3090 jfs_debug(3, "writing block %lu/%p\n",
3091 (unsigned long) bh->b_blocknr, (void *) bh);
3092 retval = io_channel_write_blk(bh->b_io,
3096 com_err(bh->b_ctx->device_name, retval,
3097 "while writing block %lu\n",
3098 (unsigned long) bh->b_blocknr);
3105 jfs_debug(3, "no-op %s for block %lu\n",
3106 rw == READ ? "read" : "write",
3107 (unsigned long) bh->b_blocknr);
3112 void mark_buffer_dirty(struct buffer_head *bh)
3117 static void mark_buffer_clean(struct buffer_head * bh)
3122 void brelse(struct buffer_head *bh)
3125 ll_rw_block(WRITE, 1, &bh);
3126 jfs_debug(3, "freeing block %lu/%p (total %d)\n",
3127 (unsigned long) bh->b_blocknr, (void *) bh, --bh_count);
3128 ext2fs_free_mem(&bh);
3131 int buffer_uptodate(struct buffer_head *bh)
3133 return bh->b_uptodate;
3136 void mark_buffer_uptodate(struct buffer_head *bh, int val)
3138 bh->b_uptodate = val;
3141 void wait_on_buffer(struct buffer_head *bh)
3143 if (!bh->b_uptodate)
3144 ll_rw_block(READ, 1, &bh);
3148 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
3150 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
3152 /* if we had an error doing journal recovery, we need a full fsck */
3154 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
3155 ext2fs_mark_super_dirty(ctx->fs);
3158 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
3160 struct ext2_super_block *sb = ctx->fs->super;
3161 struct ext2_super_block jsuper;
3162 struct problem_context pctx;
3163 struct buffer_head *bh;
3164 struct inode *j_inode = NULL;
3165 struct kdev_s *dev_fs = NULL, *dev_journal;
3166 const char *journal_name = 0;
3167 journal_t *journal = NULL;
3168 errcode_t retval = 0;
3169 io_manager io_ptr = 0;
3170 unsigned long start = 0;
3172 int ext_journal = 0;
3173 int tried_backup_jnl = 0;
3176 clear_problem_context(&pctx);
3178 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
3180 return EXT2_ET_NO_MEMORY;
3183 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
3185 retval = EXT2_ET_NO_MEMORY;
3188 dev_journal = dev_fs+1;
3190 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
3191 dev_fs->k_dev = K_DEV_FS;
3192 dev_journal->k_dev = K_DEV_JOURNAL;
3194 journal->j_dev = dev_journal;
3195 journal->j_fs_dev = dev_fs;
3196 journal->j_inode = NULL;
3197 journal->j_blocksize = ctx->fs->blocksize;
3199 if (uuid_is_null(sb->s_journal_uuid)) {
3200 if (!sb->s_journal_inum)
3201 return EXT2_ET_BAD_INODE_NUM;
3202 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
3205 retval = EXT2_ET_NO_MEMORY;
3209 j_inode->i_ctx = ctx;
3210 j_inode->i_ino = sb->s_journal_inum;
3212 if ((retval = ext2fs_read_inode(ctx->fs,
3214 &j_inode->i_ext2))) {
3216 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
3219 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
3220 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
3222 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
3223 j_inode->i_ext2.i_links_count = 1;
3224 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
3227 if (!j_inode->i_ext2.i_links_count ||
3228 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
3229 retval = EXT2_ET_NO_JOURNAL;
3230 goto try_backup_journal;
3232 if (j_inode->i_ext2.i_size / journal->j_blocksize <
3233 JFS_MIN_JOURNAL_BLOCKS) {
3234 retval = EXT2_ET_JOURNAL_TOO_SMALL;
3235 goto try_backup_journal;
3237 for (i=0; i < EXT2_N_BLOCKS; i++) {
3238 blk = j_inode->i_ext2.i_block[i];
3240 if (i < EXT2_NDIR_BLOCKS) {
3241 retval = EXT2_ET_JOURNAL_TOO_SMALL;
3242 goto try_backup_journal;
3246 if (blk < sb->s_first_data_block ||
3247 blk >= sb->s_blocks_count) {
3248 retval = EXT2_ET_BAD_BLOCK_NUM;
3249 goto try_backup_journal;
3252 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
3255 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
3261 io_ptr = inode_io_manager;
3263 journal->j_inode = j_inode;
3264 ctx->journal_io = ctx->fs->io;
3265 if ((retval = journal_bmap(journal, 0, &start)) != 0)
3270 if (!ctx->journal_name) {
3273 uuid_unparse(sb->s_journal_uuid, uuid);
3274 ctx->journal_name = blkid_get_devname(ctx->blkid,
3276 if (!ctx->journal_name)
3277 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
3279 journal_name = ctx->journal_name;
3281 if (!journal_name) {
3282 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
3283 return EXT2_ET_LOAD_EXT_JOURNAL;
3286 jfs_debug(1, "Using journal file %s\n", journal_name);
3287 io_ptr = unix_io_manager;
3291 test_io_backing_manager = io_ptr;
3292 io_ptr = test_io_manager;
3294 #ifndef USE_INODE_IO
3297 retval = io_ptr->open(journal_name, IO_FLAG_RW,
3302 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
3305 if (ctx->fs->blocksize == 1024)
3307 bh = getblk(dev_journal, start, ctx->fs->blocksize);
3309 retval = EXT2_ET_NO_MEMORY;
3312 ll_rw_block(READ, 1, &bh);
3313 if ((retval = bh->b_err) != 0)
3315 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
3318 #ifdef EXT2FS_ENABLE_SWAPFS
3319 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
3320 ext2fs_swap_super(&jsuper);
3322 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
3323 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
3324 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
3325 retval = EXT2_ET_LOAD_EXT_JOURNAL;
3328 /* Make sure the journal UUID is correct */
3329 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
3330 sizeof(jsuper.s_uuid))) {
3331 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
3332 retval = EXT2_ET_LOAD_EXT_JOURNAL;
3336 journal->j_maxlen = jsuper.s_blocks_count;
3340 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
3341 retval = EXT2_ET_NO_MEMORY;
3345 journal->j_sb_buffer = bh;
3346 journal->j_superblock = (journal_superblock_t *)bh->b_data;
3350 ext2fs_free_mem(&j_inode);
3353 *ret_journal = journal;
3358 ext2fs_free_mem(&dev_fs);
3360 ext2fs_free_mem(&j_inode);
3362 ext2fs_free_mem(&journal);
3367 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
3368 struct problem_context *pctx)
3370 struct ext2_super_block *sb = ctx->fs->super;
3371 int recover = ctx->fs->super->s_feature_incompat &
3372 EXT3_FEATURE_INCOMPAT_RECOVER;
3373 int has_journal = ctx->fs->super->s_feature_compat &
3374 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3376 if (has_journal || sb->s_journal_inum) {
3377 /* The journal inode is bogus, remove and force full fsck */
3378 pctx->ino = sb->s_journal_inum;
3379 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
3380 if (has_journal && sb->s_journal_inum)
3381 printf("*** ext3 journal has been deleted - "
3382 "filesystem is now ext2 only ***\n\n");
3383 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3384 sb->s_journal_inum = 0;
3385 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
3386 e2fsck_clear_recover(ctx, 1);
3389 return EXT2_ET_BAD_INODE_NUM;
3390 } else if (recover) {
3391 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
3392 e2fsck_clear_recover(ctx, 1);
3395 return EXT2_ET_UNSUPP_FEATURE;
3400 #define V1_SB_SIZE 0x0024
3401 static void clear_v2_journal_fields(journal_t *journal)
3403 e2fsck_t ctx = journal->j_dev->k_ctx;
3404 struct problem_context pctx;
3406 clear_problem_context(&pctx);
3408 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
3411 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
3412 ctx->fs->blocksize-V1_SB_SIZE);
3413 mark_buffer_dirty(journal->j_sb_buffer);
3417 static errcode_t e2fsck_journal_load(journal_t *journal)
3419 e2fsck_t ctx = journal->j_dev->k_ctx;
3420 journal_superblock_t *jsb;
3421 struct buffer_head *jbh = journal->j_sb_buffer;
3422 struct problem_context pctx;
3424 clear_problem_context(&pctx);
3426 ll_rw_block(READ, 1, &jbh);
3428 com_err(ctx->device_name, jbh->b_err,
3429 _("reading journal superblock\n"));
3433 jsb = journal->j_superblock;
3434 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
3435 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
3436 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3438 switch (ntohl(jsb->s_header.h_blocktype)) {
3439 case JFS_SUPERBLOCK_V1:
3440 journal->j_format_version = 1;
3441 if (jsb->s_feature_compat ||
3442 jsb->s_feature_incompat ||
3443 jsb->s_feature_ro_compat ||
3445 clear_v2_journal_fields(journal);
3448 case JFS_SUPERBLOCK_V2:
3449 journal->j_format_version = 2;
3450 if (ntohl(jsb->s_nr_users) > 1 &&
3451 uuid_is_null(ctx->fs->super->s_journal_uuid))
3452 clear_v2_journal_fields(journal);
3453 if (ntohl(jsb->s_nr_users) > 1) {
3454 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
3455 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3460 * These should never appear in a journal super block, so if
3461 * they do, the journal is badly corrupted.
3463 case JFS_DESCRIPTOR_BLOCK:
3464 case JFS_COMMIT_BLOCK:
3465 case JFS_REVOKE_BLOCK:
3466 return EXT2_ET_CORRUPT_SUPERBLOCK;
3468 /* If we don't understand the superblock major type, but there
3469 * is a magic number, then it is likely to be a new format we
3470 * just don't understand, so leave it alone. */
3472 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3475 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
3476 return EXT2_ET_UNSUPP_FEATURE;
3478 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
3479 return EXT2_ET_RO_UNSUPP_FEATURE;
3481 /* We have now checked whether we know enough about the journal
3482 * format to be able to proceed safely, so any other checks that
3483 * fail we should attempt to recover from. */
3484 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
3485 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3486 _("%s: no valid journal superblock found\n"),
3488 return EXT2_ET_CORRUPT_SUPERBLOCK;
3491 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
3492 journal->j_maxlen = ntohl(jsb->s_maxlen);
3493 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
3494 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3495 _("%s: journal too short\n"),
3497 return EXT2_ET_CORRUPT_SUPERBLOCK;
3500 journal->j_tail_sequence = ntohl(jsb->s_sequence);
3501 journal->j_transaction_sequence = journal->j_tail_sequence;
3502 journal->j_tail = ntohl(jsb->s_start);
3503 journal->j_first = ntohl(jsb->s_first);
3504 journal->j_last = ntohl(jsb->s_maxlen);
3509 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
3520 /* Leave a valid existing V1 superblock signature alone.
3521 * Anything unrecognisable we overwrite with a new V2
3524 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
3525 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
3526 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
3527 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
3530 /* Zero out everything else beyond the superblock header */
3532 p = ((char *) jsb) + sizeof(journal_header_t);
3533 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
3535 jsb->s_blocksize = htonl(ctx->fs->blocksize);
3536 jsb->s_maxlen = htonl(journal->j_maxlen);
3537 jsb->s_first = htonl(1);
3539 /* Initialize the journal sequence number so that there is "no"
3540 * chance we will find old "valid" transactions in the journal.
3541 * This avoids the need to zero the whole journal (slow to do,
3542 * and risky when we are just recovering the filesystem).
3544 uuid_generate(u.uuid);
3545 for (i = 0; i < 4; i ++)
3546 new_seq ^= u.val[i];
3547 jsb->s_sequence = htonl(new_seq);
3549 mark_buffer_dirty(journal->j_sb_buffer);
3550 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
3553 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
3555 struct problem_context *pctx)
3557 struct ext2_super_block *sb = ctx->fs->super;
3558 int recover = ctx->fs->super->s_feature_incompat &
3559 EXT3_FEATURE_INCOMPAT_RECOVER;
3561 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
3562 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
3563 e2fsck_journal_reset_super(ctx, journal->j_superblock,
3565 journal->j_transaction_sequence = 1;
3566 e2fsck_clear_recover(ctx, recover);
3569 return EXT2_ET_CORRUPT_SUPERBLOCK;
3570 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
3571 return EXT2_ET_CORRUPT_SUPERBLOCK;
3576 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
3577 int reset, int drop)
3579 journal_superblock_t *jsb;
3582 mark_buffer_clean(journal->j_sb_buffer);
3583 else if (!(ctx->options & E2F_OPT_READONLY)) {
3584 jsb = journal->j_superblock;
3585 jsb->s_sequence = htonl(journal->j_transaction_sequence);
3587 jsb->s_start = 0; /* this marks the journal as empty */
3588 mark_buffer_dirty(journal->j_sb_buffer);
3590 brelse(journal->j_sb_buffer);
3592 if (ctx->journal_io) {
3593 if (ctx->fs && ctx->fs->io != ctx->journal_io)
3594 io_channel_close(ctx->journal_io);
3595 ctx->journal_io = 0;
3598 #ifndef USE_INODE_IO
3599 if (journal->j_inode)
3600 ext2fs_free_mem(&journal->j_inode);
3602 if (journal->j_fs_dev)
3603 ext2fs_free_mem(&journal->j_fs_dev);
3604 ext2fs_free_mem(&journal);
3608 * This function makes sure that the superblock fields regarding the
3609 * journal are consistent.
3611 int e2fsck_check_ext3_journal(e2fsck_t ctx)
3613 struct ext2_super_block *sb = ctx->fs->super;
3615 int recover = ctx->fs->super->s_feature_incompat &
3616 EXT3_FEATURE_INCOMPAT_RECOVER;
3617 struct problem_context pctx;
3619 int reset = 0, force_fsck = 0;
3622 /* If we don't have any journal features, don't do anything more */
3623 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3624 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
3625 uuid_is_null(sb->s_journal_uuid))
3628 clear_problem_context(&pctx);
3629 pctx.num = sb->s_journal_inum;
3631 retval = e2fsck_get_journal(ctx, &journal);
3633 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
3634 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
3635 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
3636 (retval == EXT2_ET_NO_JOURNAL))
3637 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3641 retval = e2fsck_journal_load(journal);
3643 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
3644 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
3645 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
3647 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
3648 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
3650 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
3651 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
3652 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
3654 e2fsck_journal_release(ctx, journal, 0, 1);
3659 * We want to make the flags consistent here. We will not leave with
3660 * needs_recovery set but has_journal clear. We can't get in a loop
3661 * with -y, -n, or -p, only if a user isn't making up their mind.
3664 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
3665 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
3667 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
3669 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
3670 goto no_has_journal;
3672 * Need a full fsck if we are releasing a
3673 * journal stored on a reserved inode.
3675 force_fsck = recover ||
3676 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
3677 /* Clear all of the journal fields */
3678 sb->s_journal_inum = 0;
3679 sb->s_journal_dev = 0;
3680 memset(sb->s_journal_uuid, 0,
3681 sizeof(sb->s_journal_uuid));
3682 e2fsck_clear_recover(ctx, force_fsck);
3683 } else if (!(ctx->options & E2F_OPT_READONLY)) {
3684 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3685 ext2fs_mark_super_dirty(ctx->fs);
3689 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
3690 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
3691 journal->j_superblock->s_start != 0) {
3692 /* Print status information */
3693 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
3694 if (ctx->superblock)
3695 problem = PR_0_JOURNAL_RUN_DEFAULT;
3697 problem = PR_0_JOURNAL_RUN;
3698 if (fix_problem(ctx, problem, &pctx)) {
3699 ctx->options |= E2F_OPT_FORCE;
3700 sb->s_feature_incompat |=
3701 EXT3_FEATURE_INCOMPAT_RECOVER;
3702 ext2fs_mark_super_dirty(ctx->fs);
3703 } else if (fix_problem(ctx,
3704 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
3706 sb->s_state &= ~EXT2_VALID_FS;
3707 ext2fs_mark_super_dirty(ctx->fs);
3710 * If the user answers no to the above question, we
3711 * ignore the fact that journal apparently has data;
3712 * accidentally replaying over valid data would be far
3713 * worse than skipping a questionable recovery.
3715 * XXX should we abort with a fatal error here? What
3716 * will the ext3 kernel code do if a filesystem with
3717 * !NEEDS_RECOVERY but with a non-zero
3718 * journal->j_superblock->s_start is mounted?
3722 e2fsck_journal_release(ctx, journal, reset, 0);
3726 static errcode_t recover_ext3_journal(e2fsck_t ctx)
3731 journal_init_revoke_caches();
3732 retval = e2fsck_get_journal(ctx, &journal);
3736 retval = e2fsck_journal_load(journal);
3740 retval = journal_init_revoke(journal, 1024);
3744 retval = -journal_recover(journal);
3748 if (journal->j_superblock->s_errno) {
3749 ctx->fs->super->s_state |= EXT2_ERROR_FS;
3750 ext2fs_mark_super_dirty(ctx->fs);
3751 journal->j_superblock->s_errno = 0;
3752 mark_buffer_dirty(journal->j_sb_buffer);
3756 journal_destroy_revoke(journal);
3757 journal_destroy_revoke_caches();
3758 e2fsck_journal_release(ctx, journal, 1, 0);
3762 int e2fsck_run_ext3_journal(e2fsck_t ctx)
3764 io_manager io_ptr = ctx->fs->io->manager;
3765 int blocksize = ctx->fs->blocksize;
3766 errcode_t retval, recover_retval;
3768 printf(_("%s: recovering journal\n"), ctx->device_name);
3769 if (ctx->options & E2F_OPT_READONLY) {
3770 printf(_("%s: won't do journal recovery while read-only\n"),
3772 return EXT2_ET_FILE_RO;
3775 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
3776 ext2fs_flush(ctx->fs); /* Force out any modifications */
3778 recover_retval = recover_ext3_journal(ctx);
3781 * Reload the filesystem context to get up-to-date data from disk
3782 * because journal recovery will change the filesystem under us.
3784 ext2fs_close(ctx->fs);
3785 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
3786 ctx->superblock, blocksize, io_ptr,
3790 com_err(ctx->program_name, retval,
3791 _("while trying to re-open %s"),
3793 fatal_error(ctx, 0);
3795 ctx->fs->priv_data = ctx;
3797 /* Set the superblock flags */
3798 e2fsck_clear_recover(ctx, recover_retval);
3799 return recover_retval;
3803 * This function will move the journal inode from a visible file in
3804 * the filesystem directory hierarchy to the reserved inode if necessary.
3806 static const char * const journal_names[] = {
3807 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
3809 void e2fsck_move_ext3_journal(e2fsck_t ctx)
3811 struct ext2_super_block *sb = ctx->fs->super;
3812 struct problem_context pctx;
3813 struct ext2_inode inode;
3814 ext2_filsys fs = ctx->fs;
3817 const char * const * cpp;
3818 int group, mount_flags;
3820 clear_problem_context(&pctx);
3823 * If the filesystem is opened read-only, or there is no
3824 * journal, then do nothing.
3826 if ((ctx->options & E2F_OPT_READONLY) ||
3827 (sb->s_journal_inum == 0) ||
3828 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
3832 * Read in the journal inode
3834 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
3838 * If it's necessary to backup the journal inode, do so.
3840 if ((sb->s_jnl_backup_type == 0) ||
3841 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
3842 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
3843 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
3844 memcpy(sb->s_jnl_blocks, inode.i_block,
3846 sb->s_jnl_blocks[16] = inode.i_size;
3847 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
3848 ext2fs_mark_super_dirty(fs);
3849 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3854 * If the journal is already the hidden inode, then do nothing
3856 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
3860 * The journal inode had better have only one link and not be readable.
3862 if (inode.i_links_count != 1)
3866 * If the filesystem is mounted, or we can't tell whether
3867 * or not it's mounted, do nothing.
3869 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
3870 if (retval || (mount_flags & EXT2_MF_MOUNTED))
3874 * If we can't find the name of the journal inode, then do
3877 for (cpp = journal_names; *cpp; cpp++) {
3878 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
3879 strlen(*cpp), 0, &ino);
3880 if ((retval == 0) && (ino == sb->s_journal_inum))
3886 /* We need the inode bitmap to be loaded */
3887 retval = ext2fs_read_bitmaps(fs);
3892 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
3896 * OK, we've done all the checks, let's actually move the
3897 * journal inode. Errors at this point mean we need to force
3898 * an ext2 filesystem check.
3900 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
3902 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
3904 sb->s_journal_inum = EXT2_JOURNAL_INO;
3905 ext2fs_mark_super_dirty(fs);
3906 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3907 inode.i_links_count = 0;
3908 inode.i_dtime = time(0);
3909 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
3912 group = ext2fs_group_of_ino(fs, ino);
3913 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
3914 ext2fs_mark_ib_dirty(fs);
3915 fs->group_desc[group].bg_free_inodes_count++;
3916 fs->super->s_free_inodes_count++;
3920 pctx.errcode = retval;
3921 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
3922 fs->super->s_state &= ~EXT2_VALID_FS;
3923 ext2fs_mark_super_dirty(fs);
3928 * message.c --- print e2fsck messages (with compression)
3930 * Copyright 1996, 1997 by Theodore Ts'o
3933 * This file may be redistributed under the terms of the GNU Public
3937 * print_e2fsck_message() prints a message to the user, using
3938 * compression techniques and expansions of abbreviations.
3940 * The following % expansions are supported:
3942 * %b <blk> block number
3943 * %B <blkcount> integer
3944 * %c <blk2> block number
3945 * %Di <dirent>->ino inode number
3946 * %Dn <dirent>->name string
3947 * %Dr <dirent>->rec_len
3948 * %Dl <dirent>->name_len
3949 * %Dt <dirent>->filetype
3950 * %d <dir> inode number
3951 * %g <group> integer
3952 * %i <ino> inode number
3953 * %Is <inode> -> i_size
3954 * %IS <inode> -> i_extra_isize
3955 * %Ib <inode> -> i_blocks
3956 * %Il <inode> -> i_links_count
3957 * %Im <inode> -> i_mode
3958 * %IM <inode> -> i_mtime
3959 * %IF <inode> -> i_faddr
3960 * %If <inode> -> i_file_acl
3961 * %Id <inode> -> i_dir_acl
3962 * %Iu <inode> -> i_uid
3963 * %Ig <inode> -> i_gid
3964 * %j <ino2> inode number
3965 * %m <com_err error message>
3967 * %p ext2fs_get_pathname of directory <ino>
3968 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
3969 * the containing directory. (If dirent is NULL
3970 * then return the pathname of directory <ino2>)
3971 * %q ext2fs_get_pathname of directory <dir>
3972 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
3973 * the containing directory.
3974 * %s <str> miscellaneous string
3975 * %S backup superblock
3976 * %X <num> hexadecimal format
3978 * The following '@' expansions are supported:
3980 * @a extended attribute
3981 * @A error allocating
3985 * @C conflicts with some other fs block
3989 * @E Entry '%Dn' in %p (%i)
3991 * @F for @i %i (%Q) is
3993 * @h HTREE directory inode
4011 * This structure defines the abbreviations used by the text strings
4012 * below. The first character in the string is the index letter. An
4013 * abbreviation of the form '@<i>' is expanded by looking up the index
4014 * letter <i> in the table below.
4016 static const char *abbrevs[] = {
4017 N_("aextended attribute"),
4018 N_("Aerror allocating"),
4022 N_("Cconflicts with some other fs @b"),
4029 N_("E@e '%Dn' in %p (%i)"),
4031 N_("Ffor @i %i (%Q) is"),
4049 * Give more user friendly names to the "special" inodes.
4051 #define num_special_inodes 11
4052 static const char *special_inode_name[] =
4054 N_("<The NULL inode>"), /* 0 */
4055 N_("<The bad blocks inode>"), /* 1 */
4057 N_("<The ACL index inode>"), /* 3 */
4058 N_("<The ACL data inode>"), /* 4 */
4059 N_("<The boot loader inode>"), /* 5 */
4060 N_("<The undelete directory inode>"), /* 6 */
4061 N_("<The group descriptor inode>"), /* 7 */
4062 N_("<The journal inode>"), /* 8 */
4063 N_("<Reserved inode 9>"), /* 9 */
4064 N_("<Reserved inode 10>"), /* 10 */
4068 * This function does "safe" printing. It will convert non-printable
4069 * ASCII characters using '^' and M- notation.
4071 static void safe_print(const char *cp, int len)
4081 fputs("M-", stdout);
4084 if ((ch < 32) || (ch == 0x7f)) {
4086 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
4094 * This function prints a pathname, using the ext2fs_get_pathname
4097 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
4102 if (!dir && (ino < num_special_inodes)) {
4103 fputs(_(special_inode_name[ino]), stdout);
4107 retval = ext2fs_get_pathname(fs, dir, ino, &path);
4109 fputs("???", stdout);
4111 safe_print(path, -1);
4112 ext2fs_free_mem(&path);
4117 * This function handles the '@' expansion. We allow recursive
4118 * expansion; an @ expression can contain further '@' and '%'
4121 static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch,
4122 struct problem_context *pctx,
4125 const char **cpp, *str;
4127 /* Search for the abbreviation */
4128 for (cpp = abbrevs; *cpp; cpp++) {
4134 if (*first && islower(*str)) {
4136 fputc(toupper(*str++), stdout);
4138 print_e2fsck_message(ctx, str, pctx, *first);
4144 * This function expands '%IX' expressions
4146 static _INLINE_ void expand_inode_expression(char ch,
4147 struct problem_context *ctx)
4149 struct ext2_inode *inode;
4150 struct ext2_inode_large *large_inode;
4155 if (!ctx || !ctx->inode)
4159 large_inode = (struct ext2_inode_large *) inode;
4163 if (LINUX_S_ISDIR(inode->i_mode))
4164 printf("%u", inode->i_size);
4166 #ifdef EXT2_NO_64_TYPE
4167 if (inode->i_size_high)
4168 printf("0x%x%08x", inode->i_size_high,
4171 printf("%u", inode->i_size);
4173 printf("%llu", (inode->i_size |
4174 ((__u64) inode->i_size_high << 32)));
4179 printf("%u", large_inode->i_extra_isize);
4182 printf("%u", inode->i_blocks);
4185 printf("%d", inode->i_links_count);
4188 printf("0%o", inode->i_mode);
4191 /* The diet libc doesn't respect the TZ environemnt variable */
4193 time_str = getenv("TZ");
4196 do_gmt = !strcmp(time_str, "GMT");
4199 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
4200 printf("%.24s", time_str);
4203 printf("%u", inode->i_faddr);
4206 printf("%u", inode->i_file_acl);
4209 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
4210 inode->i_dir_acl : 0));
4213 printf("%d", (inode->i_uid |
4214 (inode->osd2.linux2.l_i_uid_high << 16)));
4217 printf("%d", (inode->i_gid |
4218 (inode->osd2.linux2.l_i_gid_high << 16)));
4222 printf("%%I%c", ch);
4228 * This function expands '%dX' expressions
4230 static _INLINE_ void expand_dirent_expression(char ch,
4231 struct problem_context *ctx)
4233 struct ext2_dir_entry *dirent;
4236 if (!ctx || !ctx->dirent)
4239 dirent = ctx->dirent;
4243 printf("%u", dirent->inode);
4246 len = dirent->name_len & 0xFF;
4247 if (len > EXT2_NAME_LEN)
4248 len = EXT2_NAME_LEN;
4249 if (len > dirent->rec_len)
4250 len = dirent->rec_len;
4251 safe_print(dirent->name, len);
4254 printf("%u", dirent->rec_len);
4257 printf("%u", dirent->name_len & 0xFF);
4260 printf("%u", dirent->name_len >> 8);
4264 printf("%%D%c", ch);
4269 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
4270 struct problem_context *ctx)
4280 printf("%u", ctx->blk);
4283 #ifdef EXT2_NO_64_TYPE
4284 printf("%d", ctx->blkcount);
4286 printf("%lld", ctx->blkcount);
4290 printf("%u", ctx->blk2);
4293 printf("%u", ctx->dir);
4296 printf("%d", ctx->group);
4299 printf("%u", ctx->ino);
4302 printf("%u", ctx->ino2);
4305 printf("%s", error_message(ctx->errcode));
4308 #ifdef EXT2_NO_64_TYPE
4309 printf("%u", ctx->num);
4311 printf("%llu", ctx->num);
4315 print_pathname(fs, ctx->ino, 0);
4318 print_pathname(fs, ctx->ino2,
4319 ctx->dirent ? ctx->dirent->inode : 0);
4322 print_pathname(fs, ctx->dir, 0);
4325 print_pathname(fs, ctx->dir, ctx->ino);
4328 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
4331 printf("%s", ctx->str ? ctx->str : "NULL");
4334 #ifdef EXT2_NO_64_TYPE
4335 printf("0x%x", ctx->num);
4337 printf("0x%llx", ctx->num);
4347 void print_e2fsck_message(e2fsck_t ctx, const char *msg,
4348 struct problem_context *pctx, int first)
4350 ext2_filsys fs = ctx->fs;
4354 e2fsck_clear_progbar(ctx);
4355 for (cp = msg; *cp; cp++) {
4358 expand_at_expression(ctx, *cp, pctx, &first);
4359 } else if (cp[0] == '%' && cp[1] == 'I') {
4361 expand_inode_expression(*cp, pctx);
4362 } else if (cp[0] == '%' && cp[1] == 'D') {
4364 expand_dirent_expression(*cp, pctx);
4365 } else if ((cp[0] == '%')) {
4367 expand_percent_expression(fs, *cp, pctx);
4369 for (i=0; cp[i]; i++)
4370 if ((cp[i] == '@') || cp[i] == '%')
4372 printf("%.*s", i, cp);
4379 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
4381 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
4384 * This file may be redistributed under the terms of the GNU Public
4388 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
4389 * and applies the following tests to each inode:
4391 * - The mode field of the inode must be legal.
4392 * - The size and block count fields of the inode are correct.
4393 * - A data block must not be used by another inode
4395 * Pass 1 also gathers the collects the following information:
4397 * - A bitmap of which inodes are in use. (inode_used_map)
4398 * - A bitmap of which inodes are directories. (inode_dir_map)
4399 * - A bitmap of which inodes are regular files. (inode_reg_map)
4400 * - A bitmap of which inodes have bad fields. (inode_bad_map)
4401 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
4402 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
4403 * - A bitmap of which blocks are in use. (block_found_map)
4404 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
4405 * - The data blocks of the directory inodes. (dir_map)
4407 * Pass 1 is designed to stash away enough information so that the
4408 * other passes should not need to read in the inode information
4409 * during the normal course of a filesystem check. (Althogh if an
4410 * inconsistency is detected, other passes may need to read in an
4413 * Note that pass 1B will be invoked if there are any duplicate blocks
4418 static int process_block(ext2_filsys fs, blk_t *blocknr,
4419 e2_blkcnt_t blockcnt, blk_t ref_blk,
4420 int ref_offset, void *priv_data);
4421 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
4422 e2_blkcnt_t blockcnt, blk_t ref_blk,
4423 int ref_offset, void *priv_data);
4424 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4426 static void mark_table_blocks(e2fsck_t ctx);
4427 static void alloc_bb_map(e2fsck_t ctx);
4428 static void alloc_imagic_map(e2fsck_t ctx);
4429 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
4430 static void handle_fs_bad_blocks(e2fsck_t ctx);
4431 static void process_inodes(e2fsck_t ctx, char *block_buf);
4432 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
4433 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
4434 dgrp_t group, void * priv_data);
4435 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4436 char *block_buf, int adjust_sign);
4437 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
4439 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
4440 struct ext2_inode * inode, int bufsize,
4443 struct process_block_struct_1 {
4445 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
4446 fragmented:1, compressed:1, bbcheck:1;
4449 e2_blkcnt_t last_block;
4450 int num_illegal_blocks;
4451 blk_t previous_block;
4452 struct ext2_inode *inode;
4453 struct problem_context *pctx;
4454 ext2fs_block_bitmap fs_meta_blocks;
4458 struct process_inode_block {
4460 struct ext2_inode inode;
4463 struct scan_callback_struct {
4469 * For the inodes to process list.
4471 static struct process_inode_block *inodes_to_process;
4472 static int process_inode_count;
4474 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
4475 EXT2_MIN_BLOCK_LOG_SIZE + 1];
4478 * Free all memory allocated by pass1 in preparation for restarting
4481 static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
4483 ext2fs_free_mem(&inodes_to_process);
4484 inodes_to_process = 0;
4488 * Check to make sure a device inode is real. Returns 1 if the device
4489 * checks out, 0 if not.
4491 * Note: this routine is now also used to check FIFO's and Sockets,
4492 * since they have the same requirement; the i_block fields should be
4495 int e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
4500 * If i_blocks is non-zero, or the index flag is set, then
4501 * this is a bogus device/fifo/socket
4503 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
4504 (inode->i_flags & EXT2_INDEX_FL))
4508 * We should be able to do the test below all the time, but
4509 * because the kernel doesn't forcibly clear the device
4510 * inode's additional i_block fields, there are some rare
4511 * occasions when a legitimate device inode will have non-zero
4512 * additional i_block fields. So for now, we only complain
4513 * when the immutable flag is set, which should never happen
4514 * for devices. (And that's when the problem is caused, since
4515 * you can't set or clear immutable flags for devices.) Once
4516 * the kernel has been fixed we can change this...
4518 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
4519 for (i=4; i < EXT2_N_BLOCKS; i++)
4520 if (inode->i_block[i])
4527 * Check to make sure a symlink inode is real. Returns 1 if the symlink
4528 * checks out, 0 if not.
4530 int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode,
4537 if ((inode->i_size_high || inode->i_size == 0) ||
4538 (inode->i_flags & EXT2_INDEX_FL))
4541 blocks = ext2fs_inode_data_blocks(fs, inode);
4543 if ((inode->i_size >= fs->blocksize) ||
4544 (blocks != fs->blocksize >> 9) ||
4545 (inode->i_block[0] < fs->super->s_first_data_block) ||
4546 (inode->i_block[0] >= fs->super->s_blocks_count))
4549 for (i = 1; i < EXT2_N_BLOCKS; i++)
4550 if (inode->i_block[i])
4553 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
4556 len = strnlen(buf, fs->blocksize);
4557 if (len == fs->blocksize)
4560 if (inode->i_size >= sizeof(inode->i_block))
4563 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
4564 if (len == sizeof(inode->i_block))
4567 if (len != inode->i_size)
4573 * If the immutable (or append-only) flag is set on the inode, offer
4576 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
4577 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
4579 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
4582 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
4585 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
4586 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4590 * If device, fifo or socket, check size is zero -- if not offer to
4593 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
4595 struct ext2_inode *inode = pctx->inode;
4597 if ((inode->i_size == 0) && (inode->i_size_high == 0))
4600 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
4604 inode->i_size_high = 0;
4605 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4608 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
4610 struct ext2_super_block *sb = ctx->fs->super;
4611 struct ext2_inode_large *inode;
4612 struct ext2_ext_attr_entry *entry;
4614 int storage_size, remain, offs;
4617 inode = (struct ext2_inode_large *) pctx->inode;
4618 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
4619 inode->i_extra_isize;
4620 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4621 inode->i_extra_isize + sizeof(__u32);
4622 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
4623 entry = (struct ext2_ext_attr_entry *) start;
4625 /* scan all entry's headers first */
4627 /* take finish entry 0UL into account */
4628 remain = storage_size - sizeof(__u32);
4631 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
4633 /* header eats this space */
4634 remain -= sizeof(struct ext2_ext_attr_entry);
4636 /* is attribute name valid? */
4637 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
4638 pctx->num = entry->e_name_len;
4639 problem = PR_1_ATTR_NAME_LEN;
4643 /* attribute len eats this space */
4644 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
4646 /* check value size */
4647 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
4648 pctx->num = entry->e_value_size;
4649 problem = PR_1_ATTR_VALUE_SIZE;
4653 /* check value placement */
4654 if (entry->e_value_offs +
4655 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
4656 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
4657 pctx->num = entry->e_value_offs;
4658 problem = PR_1_ATTR_VALUE_OFFSET;
4662 /* e_value_block must be 0 in inode's ea */
4663 if (entry->e_value_block != 0) {
4664 pctx->num = entry->e_value_block;
4665 problem = PR_1_ATTR_VALUE_BLOCK;
4669 /* e_hash must be 0 in inode's ea */
4670 if (entry->e_hash != 0) {
4671 pctx->num = entry->e_hash;
4672 problem = PR_1_ATTR_HASH;
4676 remain -= entry->e_value_size;
4677 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
4679 entry = EXT2_EXT_ATTR_NEXT(entry);
4683 * it seems like a corruption. it's very unlikely we could repair
4684 * EA(s) in automatic fashion -bzzz
4687 problem = PR_1_ATTR_HASH;
4689 if (problem == 0 || !fix_problem(ctx, problem, pctx))
4692 /* simple remove all possible EA(s) */
4693 *((__u32 *)start) = 0UL;
4694 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
4695 EXT2_INODE_SIZE(sb), "pass1");
4698 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
4700 struct ext2_super_block *sb = ctx->fs->super;
4701 struct ext2_inode_large *inode;
4705 inode = (struct ext2_inode_large *) pctx->inode;
4706 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
4707 /* this isn't large inode. so, nothing to check */
4712 printf("inode #%u, i_extra_size %d\n", pctx->ino,
4713 inode->i_extra_isize);
4715 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
4716 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
4717 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
4719 * For now we will allow i_extra_isize to be 0, but really
4720 * implementations should never allow i_extra_isize to be 0
4722 if (inode->i_extra_isize &&
4723 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
4724 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
4726 inode->i_extra_isize = min;
4727 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
4728 EXT2_INODE_SIZE(sb), "pass1");
4732 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4733 inode->i_extra_isize);
4734 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
4735 /* it seems inode has an extended attribute(s) in body */
4736 check_ea_in_inode(ctx, pctx);
4740 void e2fsck_pass1(e2fsck_t ctx)
4744 ext2_filsys fs = ctx->fs;
4746 struct ext2_inode *inode;
4747 ext2_inode_scan scan;
4749 #ifdef RESOURCE_TRACK
4750 struct resource_track rtrack;
4752 unsigned char frag, fsize;
4753 struct problem_context pctx;
4754 struct scan_callback_struct scan_struct;
4755 struct ext2_super_block *sb = ctx->fs->super;
4757 int busted_fs_time = 0;
4760 #ifdef RESOURCE_TRACK
4761 init_resource_track(&rtrack);
4763 clear_problem_context(&pctx);
4765 if (!(ctx->options & E2F_OPT_PREEN))
4766 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
4768 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4769 !(ctx->options & E2F_OPT_NO)) {
4770 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
4771 ctx->dirs_to_hash = 0;
4775 mtrace_print("Pass 1");
4778 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
4780 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
4781 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
4782 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
4783 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
4784 max_sizes = (max_sizes * (1UL << i)) - 1;
4785 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
4789 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
4792 * Allocate bitmaps structures
4794 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
4795 &ctx->inode_used_map);
4798 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4799 ctx->flags |= E2F_FLAG_ABORT;
4802 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4803 _("directory inode map"), &ctx->inode_dir_map);
4806 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4807 ctx->flags |= E2F_FLAG_ABORT;
4810 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4811 _("regular file inode map"), &ctx->inode_reg_map);
4814 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4815 ctx->flags |= E2F_FLAG_ABORT;
4818 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
4819 &ctx->block_found_map);
4822 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4823 ctx->flags |= E2F_FLAG_ABORT;
4826 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
4827 &ctx->inode_link_info);
4829 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
4830 ctx->flags |= E2F_FLAG_ABORT;
4833 inode_size = EXT2_INODE_SIZE(fs->super);
4834 inode = (struct ext2_inode *)
4835 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
4837 inodes_to_process = (struct process_inode_block *)
4838 e2fsck_allocate_memory(ctx,
4839 (ctx->process_inode_size *
4840 sizeof(struct process_inode_block)),
4841 "array of inodes to process");
4842 process_inode_count = 0;
4844 pctx.errcode = ext2fs_init_dblist(fs, 0);
4846 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
4847 ctx->flags |= E2F_FLAG_ABORT;
4852 * If the last orphan field is set, clear it, since the pass1
4853 * processing will automatically find and clear the orphans.
4854 * In the future, we may want to try using the last_orphan
4855 * linked list ourselves, but for now, we clear it so that the
4856 * ext3 mount code won't get confused.
4858 if (!(ctx->options & E2F_OPT_READONLY)) {
4859 if (fs->super->s_last_orphan) {
4860 fs->super->s_last_orphan = 0;
4861 ext2fs_mark_super_dirty(fs);
4865 mark_table_blocks(ctx);
4866 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
4867 "block interate buffer");
4868 e2fsck_use_inode_shortcuts(ctx, 1);
4869 ehandler_operation(_("doing inode scan"));
4870 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4873 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4874 ctx->flags |= E2F_FLAG_ABORT;
4877 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
4878 ctx->stashed_inode = inode;
4879 scan_struct.ctx = ctx;
4880 scan_struct.block_buf = block_buf;
4881 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
4883 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
4885 if (fs->super->s_wtime < fs->super->s_inodes_count)
4889 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
4891 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4893 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
4894 if (!ctx->inode_bb_map)
4896 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
4897 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4901 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4902 ctx->flags |= E2F_FLAG_ABORT;
4909 ctx->stashed_ino = ino;
4910 if (inode->i_links_count) {
4911 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
4912 ino, inode->i_links_count);
4914 pctx.num = inode->i_links_count;
4915 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
4916 ctx->flags |= E2F_FLAG_ABORT;
4920 if (ino == EXT2_BAD_INO) {
4921 struct process_block_struct_1 pb;
4923 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
4924 &pb.fs_meta_blocks);
4927 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4928 ctx->flags |= E2F_FLAG_ABORT;
4931 pb.ino = EXT2_BAD_INO;
4932 pb.num_blocks = pb.last_block = 0;
4933 pb.num_illegal_blocks = 0;
4934 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
4935 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
4939 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
4940 block_buf, process_bad_block, &pb);
4941 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
4943 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
4944 ctx->flags |= E2F_FLAG_ABORT;
4948 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
4949 ctx->flags |= E2F_FLAG_ABORT;
4952 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4953 clear_problem_context(&pctx);
4955 } else if (ino == EXT2_ROOT_INO) {
4957 * Make sure the root inode is a directory; if
4958 * not, offer to clear it. It will be
4959 * regnerated in pass #3.
4961 if (!LINUX_S_ISDIR(inode->i_mode)) {
4962 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
4963 inode->i_dtime = time(0);
4964 inode->i_links_count = 0;
4965 ext2fs_icount_store(ctx->inode_link_info,
4967 e2fsck_write_inode(ctx, ino, inode,
4973 * If dtime is set, offer to clear it. mke2fs
4974 * version 0.2b created filesystems with the
4975 * dtime field set for the root and lost+found
4976 * directories. We won't worry about
4977 * /lost+found, since that can be regenerated
4978 * easily. But we will fix the root directory
4979 * as a special case.
4981 if (inode->i_dtime && inode->i_links_count) {
4982 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
4984 e2fsck_write_inode(ctx, ino, inode,
4988 } else if (ino == EXT2_JOURNAL_INO) {
4989 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4990 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
4991 if (!LINUX_S_ISREG(inode->i_mode) &&
4992 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
4994 inode->i_mode = LINUX_S_IFREG;
4995 e2fsck_write_inode(ctx, ino, inode,
4998 check_blocks(ctx, &pctx, block_buf);
5001 if ((inode->i_links_count || inode->i_blocks ||
5002 inode->i_blocks || inode->i_block[0]) &&
5003 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
5005 memset(inode, 0, inode_size);
5006 ext2fs_icount_store(ctx->inode_link_info,
5008 e2fsck_write_inode_full(ctx, ino, inode,
5009 inode_size, "pass1");
5011 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
5014 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
5015 if (ino == EXT2_BOOT_LOADER_INO) {
5016 if (LINUX_S_ISDIR(inode->i_mode))
5017 problem = PR_1_RESERVED_BAD_MODE;
5018 } else if (ino == EXT2_RESIZE_INO) {
5019 if (inode->i_mode &&
5020 !LINUX_S_ISREG(inode->i_mode))
5021 problem = PR_1_RESERVED_BAD_MODE;
5023 if (inode->i_mode != 0)
5024 problem = PR_1_RESERVED_BAD_MODE;
5027 if (fix_problem(ctx, problem, &pctx)) {
5029 e2fsck_write_inode(ctx, ino, inode,
5033 check_blocks(ctx, &pctx, block_buf);
5037 * Check for inodes who might have been part of the
5038 * orphaned list linked list. They should have gotten
5039 * dealt with by now, unless the list had somehow been
5042 * FIXME: In the future, inodes which are still in use
5043 * (and which are therefore) pending truncation should
5044 * be handled specially. Right now we just clear the
5045 * dtime field, and the normal e2fsck handling of
5046 * inodes where i_size and the inode blocks are
5047 * inconsistent is to fix i_size, instead of releasing
5048 * the extra blocks. This won't catch the inodes that
5049 * was at the end of the orphan list, but it's better
5050 * than nothing. The right answer is that there
5051 * shouldn't be any bugs in the orphan list handling. :-)
5053 if (inode->i_dtime && !busted_fs_time &&
5054 inode->i_dtime < ctx->fs->super->s_inodes_count) {
5055 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
5056 inode->i_dtime = inode->i_links_count ?
5058 e2fsck_write_inode(ctx, ino, inode,
5064 * This code assumes that deleted inodes have
5065 * i_links_count set to 0.
5067 if (!inode->i_links_count) {
5068 if (!inode->i_dtime && inode->i_mode) {
5069 if (fix_problem(ctx,
5070 PR_1_ZERO_DTIME, &pctx)) {
5071 inode->i_dtime = time(0);
5072 e2fsck_write_inode(ctx, ino, inode,
5079 * n.b. 0.3c ext2fs code didn't clear i_links_count for
5080 * deleted files. Oops.
5082 * Since all new ext2 implementations get this right,
5083 * we now assume that the case of non-zero
5084 * i_links_count and non-zero dtime means that we
5085 * should keep the file, not delete it.
5088 if (inode->i_dtime) {
5089 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
5091 e2fsck_write_inode(ctx, ino, inode, "pass1");
5095 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
5096 switch (fs->super->s_creator_os) {
5098 frag = inode->osd2.linux2.l_i_frag;
5099 fsize = inode->osd2.linux2.l_i_fsize;
5102 frag = inode->osd2.hurd2.h_i_frag;
5103 fsize = inode->osd2.hurd2.h_i_fsize;
5106 frag = inode->osd2.masix2.m_i_frag;
5107 fsize = inode->osd2.masix2.m_i_fsize;
5113 if (inode->i_faddr || frag || fsize ||
5114 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
5115 mark_inode_bad(ctx, ino);
5116 if (inode->i_flags & EXT2_IMAGIC_FL) {
5118 if (!ctx->inode_imagic_map)
5119 alloc_imagic_map(ctx);
5120 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
5123 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
5124 inode->i_flags &= ~EXT2_IMAGIC_FL;
5125 e2fsck_write_inode(ctx, ino,
5131 check_inode_extra_space(ctx, &pctx);
5133 if (LINUX_S_ISDIR(inode->i_mode)) {
5134 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
5135 e2fsck_add_dir_info(ctx, ino, 0);
5136 ctx->fs_directory_count++;
5137 } else if (LINUX_S_ISREG (inode->i_mode)) {
5138 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
5139 ctx->fs_regular_count++;
5140 } else if (LINUX_S_ISCHR (inode->i_mode) &&
5141 e2fsck_pass1_check_device_inode(fs, inode)) {
5142 check_immutable(ctx, &pctx);
5143 check_size(ctx, &pctx);
5144 ctx->fs_chardev_count++;
5145 } else if (LINUX_S_ISBLK (inode->i_mode) &&
5146 e2fsck_pass1_check_device_inode(fs, inode)) {
5147 check_immutable(ctx, &pctx);
5148 check_size(ctx, &pctx);
5149 ctx->fs_blockdev_count++;
5150 } else if (LINUX_S_ISLNK (inode->i_mode) &&
5151 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
5152 check_immutable(ctx, &pctx);
5153 ctx->fs_symlinks_count++;
5154 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
5155 ctx->fs_fast_symlinks_count++;
5156 check_blocks(ctx, &pctx, block_buf);
5160 else if (LINUX_S_ISFIFO (inode->i_mode) &&
5161 e2fsck_pass1_check_device_inode(fs, inode)) {
5162 check_immutable(ctx, &pctx);
5163 check_size(ctx, &pctx);
5164 ctx->fs_fifo_count++;
5165 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
5166 e2fsck_pass1_check_device_inode(fs, inode)) {
5167 check_immutable(ctx, &pctx);
5168 check_size(ctx, &pctx);
5169 ctx->fs_sockets_count++;
5171 mark_inode_bad(ctx, ino);
5172 if (inode->i_block[EXT2_IND_BLOCK])
5173 ctx->fs_ind_count++;
5174 if (inode->i_block[EXT2_DIND_BLOCK])
5175 ctx->fs_dind_count++;
5176 if (inode->i_block[EXT2_TIND_BLOCK])
5177 ctx->fs_tind_count++;
5178 if (inode->i_block[EXT2_IND_BLOCK] ||
5179 inode->i_block[EXT2_DIND_BLOCK] ||
5180 inode->i_block[EXT2_TIND_BLOCK] ||
5181 inode->i_file_acl) {
5182 inodes_to_process[process_inode_count].ino = ino;
5183 inodes_to_process[process_inode_count].inode = *inode;
5184 process_inode_count++;
5186 check_blocks(ctx, &pctx, block_buf);
5188 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5191 if (process_inode_count >= ctx->process_inode_size) {
5192 process_inodes(ctx, block_buf);
5194 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5198 process_inodes(ctx, block_buf);
5199 ext2fs_close_inode_scan(scan);
5200 ehandler_operation(0);
5203 * If any extended attribute blocks' reference counts need to
5204 * be adjusted, either up (ctx->refcount_extra), or down
5205 * (ctx->refcount), then fix them.
5207 if (ctx->refcount) {
5208 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
5209 ea_refcount_free(ctx->refcount);
5212 if (ctx->refcount_extra) {
5213 adjust_extattr_refcount(ctx, ctx->refcount_extra,
5215 ea_refcount_free(ctx->refcount_extra);
5216 ctx->refcount_extra = 0;
5219 if (ctx->invalid_bitmaps)
5220 handle_fs_bad_blocks(ctx);
5222 /* We don't need the block_ea_map any more */
5223 if (ctx->block_ea_map) {
5224 ext2fs_free_block_bitmap(ctx->block_ea_map);
5225 ctx->block_ea_map = 0;
5228 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
5229 ext2fs_block_bitmap save_bmap;
5231 save_bmap = fs->block_map;
5232 fs->block_map = ctx->block_found_map;
5233 clear_problem_context(&pctx);
5234 pctx.errcode = ext2fs_create_resize_inode(fs);
5236 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
5237 /* Should never get here */
5238 ctx->flags |= E2F_FLAG_ABORT;
5241 fs->block_map = save_bmap;
5242 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
5245 if (ctx->flags & E2F_FLAG_RESTART) {
5247 * Only the master copy of the superblock and block
5248 * group descriptors are going to be written during a
5249 * restart, so set the superblock to be used to be the
5250 * master superblock.
5252 ctx->use_superblock = 0;
5257 if (ctx->block_dup_map) {
5258 if (ctx->options & E2F_OPT_PREEN) {
5259 clear_problem_context(&pctx);
5260 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
5262 e2fsck_pass1_dupblocks(ctx, block_buf);
5264 ext2fs_free_mem(&inodes_to_process);
5266 e2fsck_use_inode_shortcuts(ctx, 0);
5268 ext2fs_free_mem(&block_buf);
5269 ext2fs_free_mem(&inode);
5271 #ifdef RESOURCE_TRACK
5272 if (ctx->options & E2F_OPT_TIME2) {
5273 e2fsck_clear_progbar(ctx);
5274 print_resource_track(_("Pass 1"), &rtrack);
5280 * When the inode_scan routines call this callback at the end of the
5281 * glock group, call process_inodes.
5283 static errcode_t scan_callback(ext2_filsys fs,
5284 ext2_inode_scan scan EXT2FS_ATTR((unused)),
5285 dgrp_t group, void * priv_data)
5287 struct scan_callback_struct *scan_struct;
5290 scan_struct = (struct scan_callback_struct *) priv_data;
5291 ctx = scan_struct->ctx;
5293 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
5296 if ((ctx->progress)(ctx, 1, group+1,
5297 ctx->fs->group_desc_count))
5298 return EXT2_ET_CANCEL_REQUESTED;
5304 * Process the inodes in the "inodes to process" list.
5306 static void process_inodes(e2fsck_t ctx, char *block_buf)
5309 struct ext2_inode *old_stashed_inode;
5310 ext2_ino_t old_stashed_ino;
5311 const char *old_operation;
5313 struct problem_context pctx;
5316 printf("begin process_inodes: ");
5318 if (process_inode_count == 0)
5320 old_operation = ehandler_operation(0);
5321 old_stashed_inode = ctx->stashed_inode;
5322 old_stashed_ino = ctx->stashed_ino;
5323 qsort(inodes_to_process, process_inode_count,
5324 sizeof(struct process_inode_block), process_inode_cmp);
5325 clear_problem_context(&pctx);
5326 for (i=0; i < process_inode_count; i++) {
5327 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
5328 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
5331 printf("%u ", pctx.ino);
5333 sprintf(buf, _("reading indirect blocks of inode %u"),
5335 ehandler_operation(buf);
5336 check_blocks(ctx, &pctx, block_buf);
5337 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5340 ctx->stashed_inode = old_stashed_inode;
5341 ctx->stashed_ino = old_stashed_ino;
5342 process_inode_count = 0;
5344 printf("end process inodes\n");
5346 ehandler_operation(old_operation);
5349 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
5351 const struct process_inode_block *ib_a =
5352 (const struct process_inode_block *) a;
5353 const struct process_inode_block *ib_b =
5354 (const struct process_inode_block *) b;
5357 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
5358 ib_b->inode.i_block[EXT2_IND_BLOCK]);
5360 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
5365 * Mark an inode as being bad in some what
5367 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
5369 struct problem_context pctx;
5371 if (!ctx->inode_bad_map) {
5372 clear_problem_context(&pctx);
5374 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5375 _("bad inode map"), &ctx->inode_bad_map);
5378 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5379 /* Should never get here */
5380 ctx->flags |= E2F_FLAG_ABORT;
5384 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
5389 * This procedure will allocate the inode "bb" (badblock) map table
5391 static void alloc_bb_map(e2fsck_t ctx)
5393 struct problem_context pctx;
5395 clear_problem_context(&pctx);
5396 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5397 _("inode in bad block map"),
5398 &ctx->inode_bb_map);
5401 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5402 /* Should never get here */
5403 ctx->flags |= E2F_FLAG_ABORT;
5409 * This procedure will allocate the inode imagic table
5411 static void alloc_imagic_map(e2fsck_t ctx)
5413 struct problem_context pctx;
5415 clear_problem_context(&pctx);
5416 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5417 _("imagic inode map"),
5418 &ctx->inode_imagic_map);
5421 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5422 /* Should never get here */
5423 ctx->flags |= E2F_FLAG_ABORT;
5429 * Marks a block as in use, setting the dup_map if it's been set
5430 * already. Called by process_block and process_bad_block.
5432 * WARNING: Assumes checks have already been done to make sure block
5433 * is valid. This is true in both process_block and process_bad_block.
5435 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
5437 struct problem_context pctx;
5439 clear_problem_context(&pctx);
5441 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
5442 if (!ctx->block_dup_map) {
5443 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
5444 _("multiply claimed block map"),
5445 &ctx->block_dup_map);
5448 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
5450 /* Should never get here */
5451 ctx->flags |= E2F_FLAG_ABORT;
5455 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
5457 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
5462 * Adjust the extended attribute block's reference counts at the end
5463 * of pass 1, either by subtracting out references for EA blocks that
5464 * are still referenced in ctx->refcount, or by adding references for
5465 * EA blocks that had extra references as accounted for in
5466 * ctx->refcount_extra.
5468 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
5469 char *block_buf, int adjust_sign)
5471 struct ext2_ext_attr_header *header;
5472 struct problem_context pctx;
5473 ext2_filsys fs = ctx->fs;
5478 clear_problem_context(&pctx);
5480 ea_refcount_intr_begin(refcount);
5482 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
5485 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5487 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
5490 header = (struct ext2_ext_attr_header *) block_buf;
5491 pctx.blkcount = header->h_refcount;
5492 should_be = header->h_refcount + adjust_sign * count;
5493 pctx.num = should_be;
5494 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
5495 header->h_refcount = should_be;
5496 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
5499 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
5507 * Handle processing the extended attribute blocks
5509 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
5512 ext2_filsys fs = ctx->fs;
5513 ext2_ino_t ino = pctx->ino;
5514 struct ext2_inode *inode = pctx->inode;
5517 struct ext2_ext_attr_header *header;
5518 struct ext2_ext_attr_entry *entry;
5522 blk = inode->i_file_acl;
5527 * If the Extended attribute flag isn't set, then a non-zero
5528 * file acl means that the inode is corrupted.
5530 * Or if the extended attribute block is an invalid block,
5531 * then the inode is also corrupted.
5533 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
5534 (blk < fs->super->s_first_data_block) ||
5535 (blk >= fs->super->s_blocks_count)) {
5536 mark_inode_bad(ctx, ino);
5540 /* If ea bitmap hasn't been allocated, create it */
5541 if (!ctx->block_ea_map) {
5542 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
5543 _("ext attr block map"),
5544 &ctx->block_ea_map);
5545 if (pctx->errcode) {
5547 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
5548 ctx->flags |= E2F_FLAG_ABORT;
5553 /* Create the EA refcount structure if necessary */
5554 if (!ctx->refcount) {
5555 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
5556 if (pctx->errcode) {
5558 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5559 ctx->flags |= E2F_FLAG_ABORT;
5565 /* Debugging text */
5566 printf("Inode %u has EA block %u\n", ino, blk);
5569 /* Have we seen this EA block before? */
5570 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
5571 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
5573 /* Ooops, this EA was referenced more than it stated */
5574 if (!ctx->refcount_extra) {
5575 pctx->errcode = ea_refcount_create(0,
5576 &ctx->refcount_extra);
5577 if (pctx->errcode) {
5579 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5580 ctx->flags |= E2F_FLAG_ABORT;
5584 ea_refcount_increment(ctx->refcount_extra, blk, 0);
5589 * OK, we haven't seen this EA block yet. So we need to
5593 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5594 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
5596 header = (struct ext2_ext_attr_header *) block_buf;
5597 pctx->blk = inode->i_file_acl;
5598 if (((ctx->ext_attr_ver == 1) &&
5599 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
5600 ((ctx->ext_attr_ver == 2) &&
5601 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
5602 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
5606 if (header->h_blocks != 1) {
5607 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
5611 region = region_create(0, fs->blocksize);
5613 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
5614 ctx->flags |= E2F_FLAG_ABORT;
5617 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
5618 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5622 entry = (struct ext2_ext_attr_entry *)(header+1);
5623 end = block_buf + fs->blocksize;
5624 while ((char *)entry < end && *(__u32 *)entry) {
5625 if (region_allocate(region, (char *)entry - (char *)header,
5626 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
5627 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5630 if ((ctx->ext_attr_ver == 1 &&
5631 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
5632 (ctx->ext_attr_ver == 2 &&
5633 entry->e_name_index == 0)) {
5634 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
5637 if (entry->e_value_block != 0) {
5638 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
5641 if (entry->e_value_size &&
5642 region_allocate(region, entry->e_value_offs,
5643 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
5644 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5647 entry = EXT2_EXT_ATTR_NEXT(entry);
5649 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
5650 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5653 region_free(region);
5655 count = header->h_refcount - 1;
5657 ea_refcount_store(ctx->refcount, blk, count);
5658 mark_block_used(ctx, blk);
5659 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
5664 inode->i_file_acl = 0;
5665 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
5669 /* Returns 1 if bad htree, 0 if OK */
5670 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
5671 ext2_ino_t ino EXT2FS_ATTR((unused)),
5672 struct ext2_inode *inode,
5675 struct ext2_dx_root_info *root;
5676 ext2_filsys fs = ctx->fs;
5680 if ((!LINUX_S_ISDIR(inode->i_mode) &&
5681 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
5682 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
5683 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
5686 blk = inode->i_block[0];
5688 (blk < fs->super->s_first_data_block) ||
5689 (blk >= fs->super->s_blocks_count)) &&
5690 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5693 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
5694 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5697 /* XXX should check that beginning matches a directory */
5698 root = (struct ext2_dx_root_info *) (block_buf + 24);
5700 if ((root->reserved_zero || root->info_length < 8) &&
5701 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5704 pctx->num = root->hash_version;
5705 if ((root->hash_version != EXT2_HASH_LEGACY) &&
5706 (root->hash_version != EXT2_HASH_HALF_MD4) &&
5707 (root->hash_version != EXT2_HASH_TEA) &&
5708 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
5711 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
5712 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
5715 pctx->num = root->indirect_levels;
5716 if ((root->indirect_levels > 1) &&
5717 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
5724 * This subroutine is called on each inode to account for all of the
5725 * blocks used by that inode.
5727 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
5730 ext2_filsys fs = ctx->fs;
5731 struct process_block_struct_1 pb;
5732 ext2_ino_t ino = pctx->ino;
5733 struct ext2_inode *inode = pctx->inode;
5735 int dirty_inode = 0;
5741 pb.num_illegal_blocks = 0;
5742 pb.suppress = 0; pb.clear = 0;
5745 pb.previous_block = 0;
5746 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
5747 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
5748 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
5755 if (inode->i_flags & EXT2_COMPRBLK_FL) {
5756 if (fs->super->s_feature_incompat &
5757 EXT2_FEATURE_INCOMPAT_COMPRESSION)
5760 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
5761 inode->i_flags &= ~EXT2_COMPRBLK_FL;
5767 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
5770 if (ext2fs_inode_has_valid_blocks(inode))
5771 pctx->errcode = ext2fs_block_iterate2(fs, ino,
5772 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
5773 block_buf, process_block, &pb);
5774 end_problem_latch(ctx, PR_LATCH_BLOCK);
5775 end_problem_latch(ctx, PR_LATCH_TOOBIG);
5776 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5779 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
5781 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
5782 ctx->fs_fragmented++;
5785 inode->i_links_count = 0;
5786 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5787 inode->i_dtime = time(0);
5789 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5790 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5791 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5793 * The inode was probably partially accounted for
5794 * before processing was aborted, so we need to
5795 * restart the pass 1 scan.
5797 ctx->flags |= E2F_FLAG_RESTART;
5801 if (inode->i_flags & EXT2_INDEX_FL) {
5802 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
5803 inode->i_flags &= ~EXT2_INDEX_FL;
5807 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
5811 if (ctx->dirs_to_hash && pb.is_dir &&
5812 !(inode->i_flags & EXT2_INDEX_FL) &&
5813 ((inode->i_size / fs->blocksize) >= 3))
5814 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
5816 if (!pb.num_blocks && pb.is_dir) {
5817 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
5818 inode->i_links_count = 0;
5819 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5820 inode->i_dtime = time(0);
5822 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5823 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5824 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5825 ctx->fs_directory_count--;
5830 pb.num_blocks *= (fs->blocksize / 512);
5832 printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
5833 ino, inode->i_size, pb.last_block, inode->i_blocks,
5837 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
5838 if (nblock > (pb.last_block + 1))
5840 else if (nblock < (pb.last_block + 1)) {
5841 if (((pb.last_block + 1) - nblock) >
5842 fs->super->s_prealloc_dir_blocks)
5846 size = EXT2_I_SIZE(inode);
5847 if ((pb.last_block >= 0) &&
5848 (size < (__u64) pb.last_block * fs->blocksize))
5850 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
5853 /* i_size for symlinks is checked elsewhere */
5854 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
5855 pctx->num = (pb.last_block+1) * fs->blocksize;
5856 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
5857 inode->i_size = pctx->num;
5858 if (!LINUX_S_ISDIR(inode->i_mode))
5859 inode->i_size_high = pctx->num >> 32;
5864 if (LINUX_S_ISREG(inode->i_mode) &&
5865 (inode->i_size_high || inode->i_size & 0x80000000UL))
5867 if (pb.num_blocks != inode->i_blocks) {
5868 pctx->num = pb.num_blocks;
5869 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
5870 inode->i_blocks = pb.num_blocks;
5877 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
5882 * Helper function called by process block when an illegal block is
5883 * found. It returns a description about why the block is illegal
5885 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
5889 static char problem[80];
5891 super = fs->super->s_first_data_block;
5892 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
5893 if (block < super) {
5894 sprintf(problem, "< FIRSTBLOCK (%u)", super);
5896 } else if (block >= fs->super->s_blocks_count) {
5897 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
5900 for (i = 0; i < fs->group_desc_count; i++) {
5901 if (block == super) {
5902 sprintf(problem, "is the superblock in group %d", i);
5905 if (block > super &&
5906 block <= (super + fs->desc_blocks)) {
5907 sprintf(problem, "is in the group descriptors "
5911 if (block == fs->group_desc[i].bg_block_bitmap) {
5912 sprintf(problem, "is the block bitmap of group %d", i);
5915 if (block == fs->group_desc[i].bg_inode_bitmap) {
5916 sprintf(problem, "is the inode bitmap of group %d", i);
5919 if (block >= fs->group_desc[i].bg_inode_table &&
5920 (block < fs->group_desc[i].bg_inode_table
5921 + fs->inode_blocks_per_group)) {
5922 sprintf(problem, "is in the inode table of group %d",
5926 super += fs->super->s_blocks_per_group;
5933 * This is a helper function for check_blocks().
5935 static int process_block(ext2_filsys fs,
5937 e2_blkcnt_t blockcnt,
5938 blk_t ref_block EXT2FS_ATTR((unused)),
5939 int ref_offset EXT2FS_ATTR((unused)),
5942 struct process_block_struct_1 *p;
5943 struct problem_context *pctx;
5944 blk_t blk = *block_nr;
5949 p = (struct process_block_struct_1 *) priv_data;
5953 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
5954 /* todo: Check that the comprblk_fl is high, that the
5955 blkaddr pattern looks right (all non-holes up to
5956 first EXT2FS_COMPRESSED_BLKADDR, then all
5957 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
5958 that the feature_incompat bit is high, and that the
5959 inode is a regular file. If we're doing a "full
5960 check" (a concept introduced to e2fsck by e2compr,
5961 meaning that we look at data blocks as well as
5962 metadata) then call some library routine that
5963 checks the compressed data. I'll have to think
5964 about this, because one particularly important
5965 problem to be able to fix is to recalculate the
5966 cluster size if necessary. I think that perhaps
5967 we'd better do most/all e2compr-specific checks
5968 separately, after the non-e2compr checks. If not
5969 doing a full check, it may be useful to test that
5970 the personality is linux; e.g. if it isn't then
5971 perhaps this really is just an illegal block. */
5976 if (p->is_dir == 0) {
5978 * Should never happen, since only directories
5979 * get called with BLOCK_FLAG_HOLE
5982 printf("process_block() called with blk == 0, "
5983 "blockcnt=%d, inode %lu???\n",
5990 if (blockcnt * fs->blocksize < p->inode->i_size) {
5992 printf("Missing block (#%d) in directory inode %lu!\n",
6001 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
6006 * Simplistic fragmentation check. We merely require that the
6007 * file be contiguous. (Which can never be true for really
6008 * big files that are greater than a block group.)
6010 if (!HOLE_BLKADDR(p->previous_block)) {
6011 if (p->previous_block+1 != blk)
6014 p->previous_block = blk;
6016 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
6017 problem = PR_1_TOOBIG_DIR;
6018 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
6019 problem = PR_1_TOOBIG_REG;
6020 if (!p->is_dir && !p->is_reg && blockcnt > 0)
6021 problem = PR_1_TOOBIG_SYMLINK;
6023 if (blk < fs->super->s_first_data_block ||
6024 blk >= fs->super->s_blocks_count)
6025 problem = PR_1_ILLEGAL_BLOCK_NUM;
6028 p->num_illegal_blocks++;
6029 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
6030 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
6034 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
6036 set_latch_flags(PR_LATCH_BLOCK,
6041 pctx->blkcount = blockcnt;
6042 if (fix_problem(ctx, problem, pctx)) {
6043 blk = *block_nr = 0;
6044 ret_code = BLOCK_CHANGED;
6050 if (p->ino == EXT2_RESIZE_INO) {
6052 * The resize inode has already be sanity checked
6053 * during pass #0 (the superblock checks). All we
6054 * have to do is mark the double indirect block as
6055 * being in use; all of the other blocks are handled
6056 * by mark_table_blocks()).
6058 if (blockcnt == BLOCK_COUNT_DIND)
6059 mark_block_used(ctx, blk);
6061 mark_block_used(ctx, blk);
6064 p->last_block = blockcnt;
6066 if (p->is_dir && (blockcnt >= 0)) {
6067 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
6069 if (pctx->errcode) {
6071 pctx->num = blockcnt;
6072 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
6073 /* Should never get here */
6074 ctx->flags |= E2F_FLAG_ABORT;
6081 static int process_bad_block(ext2_filsys fs,
6083 e2_blkcnt_t blockcnt,
6084 blk_t ref_block EXT2FS_ATTR((unused)),
6085 int ref_offset EXT2FS_ATTR((unused)),
6088 struct process_block_struct_1 *p;
6089 blk_t blk = *block_nr;
6092 struct problem_context *pctx;
6096 * Note: This function processes blocks for the bad blocks
6097 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
6103 p = (struct process_block_struct_1 *) priv_data;
6107 pctx->ino = EXT2_BAD_INO;
6109 pctx->blkcount = blockcnt;
6111 if ((blk < fs->super->s_first_data_block) ||
6112 (blk >= fs->super->s_blocks_count)) {
6113 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
6115 return BLOCK_CHANGED;
6121 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
6123 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
6125 return BLOCK_CHANGED;
6127 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
6130 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
6133 return BLOCK_CHANGED;
6135 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6138 mark_block_used(ctx, blk);
6142 printf ("DEBUG: Marking %u as bad.\n", blk);
6144 ctx->fs_badblocks_count++;
6146 * If the block is not used, then mark it as used and return.
6147 * If it is already marked as found, this must mean that
6148 * there's an overlap between the filesystem table blocks
6149 * (bitmaps and inode table) and the bad block list.
6151 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
6152 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6156 * Try to find the where the filesystem block was used...
6158 first_block = fs->super->s_first_data_block;
6160 for (i = 0; i < fs->group_desc_count; i++ ) {
6163 if (!ext2fs_bg_has_super(fs, i))
6165 if (blk == first_block) {
6167 if (fix_problem(ctx,
6168 PR_1_BAD_PRIMARY_SUPERBLOCK,
6171 return BLOCK_CHANGED;
6175 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
6178 if ((blk > first_block) &&
6179 (blk <= first_block + fs->desc_blocks)) {
6181 pctx->blk = *block_nr;
6182 if (fix_problem(ctx,
6183 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
6185 return BLOCK_CHANGED;
6189 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
6193 if (blk == fs->group_desc[i].bg_block_bitmap) {
6194 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
6195 ctx->invalid_block_bitmap_flag[i]++;
6196 ctx->invalid_bitmaps++;
6200 if (blk == fs->group_desc[i].bg_inode_bitmap) {
6201 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
6202 ctx->invalid_inode_bitmap_flag[i]++;
6203 ctx->invalid_bitmaps++;
6207 if ((blk >= fs->group_desc[i].bg_inode_table) &&
6208 (blk < (fs->group_desc[i].bg_inode_table +
6209 fs->inode_blocks_per_group))) {
6211 * If there are bad blocks in the inode table,
6212 * the inode scan code will try to do
6213 * something reasonable automatically.
6217 first_block += fs->super->s_blocks_per_group;
6220 * If we've gotten to this point, then the only
6221 * possibility is that the bad block inode meta data
6222 * is using a bad block.
6224 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
6225 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
6226 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
6228 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
6230 return BLOCK_CHANGED;
6232 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6239 /* Warn user that the block wasn't claimed */
6240 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
6245 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
6246 const char *name, int num, blk_t *new_block)
6248 ext2_filsys fs = ctx->fs;
6249 blk_t old_block = *new_block;
6252 struct problem_context pctx;
6254 clear_problem_context(&pctx);
6257 pctx.blk = old_block;
6260 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
6261 first_block + fs->super->s_blocks_per_group,
6262 num, ctx->block_found_map, new_block);
6265 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
6266 ext2fs_unmark_valid(fs);
6269 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
6271 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
6272 ext2fs_unmark_valid(fs);
6275 ext2fs_mark_super_dirty(fs);
6276 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
6277 pctx.blk2 = *new_block;
6278 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
6279 PR_1_RELOC_TO), &pctx);
6281 for (i = 0; i < num; i++) {
6283 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
6285 pctx.errcode = io_channel_read_blk(fs->io,
6286 old_block + i, 1, buf);
6288 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
6290 memset(buf, 0, fs->blocksize);
6292 pctx.blk = (*new_block) + i;
6293 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
6296 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
6298 ext2fs_free_mem(&buf);
6302 * This routine gets called at the end of pass 1 if bad blocks are
6303 * detected in the superblock, group descriptors, inode_bitmaps, or
6304 * block bitmaps. At this point, all of the blocks have been mapped
6305 * out, so we can try to allocate new block(s) to replace the bad
6308 static void handle_fs_bad_blocks(e2fsck_t ctx)
6310 ext2_filsys fs = ctx->fs;
6312 int first_block = fs->super->s_first_data_block;
6314 for (i = 0; i < fs->group_desc_count; i++) {
6315 if (ctx->invalid_block_bitmap_flag[i]) {
6316 new_table_block(ctx, first_block, i, _("block bitmap"),
6317 1, &fs->group_desc[i].bg_block_bitmap);
6319 if (ctx->invalid_inode_bitmap_flag[i]) {
6320 new_table_block(ctx, first_block, i, _("inode bitmap"),
6321 1, &fs->group_desc[i].bg_inode_bitmap);
6323 if (ctx->invalid_inode_table_flag[i]) {
6324 new_table_block(ctx, first_block, i, _("inode table"),
6325 fs->inode_blocks_per_group,
6326 &fs->group_desc[i].bg_inode_table);
6327 ctx->flags |= E2F_FLAG_RESTART;
6329 first_block += fs->super->s_blocks_per_group;
6331 ctx->invalid_bitmaps = 0;
6335 * This routine marks all blocks which are used by the superblock,
6336 * group descriptors, inode bitmaps, and block bitmaps.
6338 static void mark_table_blocks(e2fsck_t ctx)
6340 ext2_filsys fs = ctx->fs;
6344 struct problem_context pctx;
6346 clear_problem_context(&pctx);
6348 block = fs->super->s_first_data_block;
6349 for (i = 0; i < fs->group_desc_count; i++) {
6352 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
6355 * Mark the blocks used for the inode table
6357 if (fs->group_desc[i].bg_inode_table) {
6358 for (j = 0, b = fs->group_desc[i].bg_inode_table;
6359 j < fs->inode_blocks_per_group;
6361 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6364 if (fix_problem(ctx,
6365 PR_1_ITABLE_CONFLICT, &pctx)) {
6366 ctx->invalid_inode_table_flag[i]++;
6367 ctx->invalid_bitmaps++;
6370 ext2fs_mark_block_bitmap(ctx->block_found_map,
6377 * Mark block used for the block bitmap
6379 if (fs->group_desc[i].bg_block_bitmap) {
6380 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6381 fs->group_desc[i].bg_block_bitmap)) {
6382 pctx.blk = fs->group_desc[i].bg_block_bitmap;
6383 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
6384 ctx->invalid_block_bitmap_flag[i]++;
6385 ctx->invalid_bitmaps++;
6388 ext2fs_mark_block_bitmap(ctx->block_found_map,
6389 fs->group_desc[i].bg_block_bitmap);
6394 * Mark block used for the inode bitmap
6396 if (fs->group_desc[i].bg_inode_bitmap) {
6397 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6398 fs->group_desc[i].bg_inode_bitmap)) {
6399 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
6400 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
6401 ctx->invalid_inode_bitmap_flag[i]++;
6402 ctx->invalid_bitmaps++;
6405 ext2fs_mark_block_bitmap(ctx->block_found_map,
6406 fs->group_desc[i].bg_inode_bitmap);
6409 block += fs->super->s_blocks_per_group;
6414 * Thes subroutines short circuits ext2fs_get_blocks and
6415 * ext2fs_check_directory; we use them since we already have the inode
6416 * structure, so there's no point in letting the ext2fs library read
6419 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
6422 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6425 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6426 return EXT2_ET_CALLBACK_NOTHANDLED;
6428 for (i=0; i < EXT2_N_BLOCKS; i++)
6429 blocks[i] = ctx->stashed_inode->i_block[i];
6433 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
6434 struct ext2_inode *inode)
6436 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6438 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6439 return EXT2_ET_CALLBACK_NOTHANDLED;
6440 *inode = *ctx->stashed_inode;
6444 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
6445 struct ext2_inode *inode)
6447 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6449 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
6450 *ctx->stashed_inode = *inode;
6451 return EXT2_ET_CALLBACK_NOTHANDLED;
6454 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
6456 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6458 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6459 return EXT2_ET_CALLBACK_NOTHANDLED;
6461 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
6462 return EXT2_ET_NO_DIRECTORY;
6466 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
6468 ext2_filsys fs = ctx->fs;
6471 fs->get_blocks = pass1_get_blocks;
6472 fs->check_directory = pass1_check_directory;
6473 fs->read_inode = pass1_read_inode;
6474 fs->write_inode = pass1_write_inode;
6475 ctx->stashed_ino = 0;
6478 fs->check_directory = 0;
6480 fs->write_inode = 0;
6484 * pass1b.c --- Pass #1b of e2fsck
6486 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
6487 * only invoked if pass 1 discovered blocks which are in use by more
6490 * Pass1B scans the data blocks of all the inodes again, generating a
6491 * complete list of duplicate blocks and which inodes have claimed
6494 * Pass1C does a tree-traversal of the filesystem, to determine the
6495 * parent directories of these inodes. This step is necessary so that
6496 * e2fsck can print out the pathnames of affected inodes.
6498 * Pass1D is a reconciliation pass. For each inode with duplicate
6499 * blocks, the user is prompted if s/he would like to clone the file
6500 * (so that the file gets a fresh copy of the duplicated blocks) or
6501 * simply to delete the file.
6503 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6506 * This file may be redistributed under the terms of the GNU Public
6513 /* Needed for architectures where sizeof(int) != sizeof(void *) */
6514 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
6515 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
6517 /* Define an extension to the ext2 library's block count information */
6518 #define BLOCK_COUNT_EXTATTR (-5)
6522 struct block_el *next;
6527 struct inode_el *next;
6532 struct inode_el *inode_list;
6536 * This structure stores information about a particular inode which
6537 * is sharing blocks with other inodes. This information is collected
6538 * to display to the user, so that the user knows what files he or she
6539 * is dealing with, when trying to decide how to resolve the conflict
6540 * of multiply-claimed blocks.
6545 struct ext2_inode inode;
6546 struct block_el *block_list;
6549 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
6550 e2_blkcnt_t blockcnt, blk_t ref_blk,
6551 int ref_offset, void *priv_data);
6552 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6553 struct dup_inode *dp, char *block_buf);
6554 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6555 struct dup_inode *dp, char* block_buf);
6556 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
6558 static void pass1b(e2fsck_t ctx, char *block_buf);
6559 static void pass1c(e2fsck_t ctx, char *block_buf);
6560 static void pass1d(e2fsck_t ctx, char *block_buf);
6562 static int dup_inode_count = 0;
6564 static dict_t blk_dict, ino_dict;
6566 static ext2fs_inode_bitmap inode_dup_map;
6568 static int dict_int_cmp(const void *a, const void *b)
6579 * Add a duplicate block record
6581 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
6582 struct ext2_inode *inode)
6585 struct dup_block *db;
6586 struct dup_inode *di;
6587 struct block_el *blk_el;
6588 struct inode_el *ino_el;
6590 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6592 db = (struct dup_block *) dnode_get(n);
6594 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
6595 sizeof(struct dup_block), "duplicate block header");
6598 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
6600 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
6601 sizeof(struct inode_el), "inode element");
6602 ino_el->inode = ino;
6603 ino_el->next = db->inode_list;
6604 db->inode_list = ino_el;
6607 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
6609 di = (struct dup_inode *) dnode_get(n);
6611 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
6612 sizeof(struct dup_inode), "duplicate inode header");
6613 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
6614 di->num_dupblocks = 0;
6617 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
6619 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
6620 sizeof(struct block_el), "block element");
6621 blk_el->block = blk;
6622 blk_el->next = di->block_list;
6623 di->block_list = blk_el;
6624 di->num_dupblocks++;
6628 * Free a duplicate inode record
6630 static void inode_dnode_free(dnode_t *node,
6631 void *context EXT2FS_ATTR((unused)))
6633 struct dup_inode *di;
6634 struct block_el *p, *next;
6636 di = (struct dup_inode *) dnode_get(node);
6637 for (p = di->block_list; p; p = next) {
6645 * Free a duplicate block record
6647 static void block_dnode_free(dnode_t *node,
6648 void *context EXT2FS_ATTR((unused)))
6650 struct dup_block *db;
6651 struct inode_el *p, *next;
6653 db = (struct dup_block *) dnode_get(node);
6654 for (p = db->inode_list; p; p = next) {
6663 * Main procedure for handling duplicate blocks
6665 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
6667 ext2_filsys fs = ctx->fs;
6668 struct problem_context pctx;
6670 clear_problem_context(&pctx);
6672 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
6673 _("multiply claimed inode map"), &inode_dup_map);
6675 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
6676 ctx->flags |= E2F_FLAG_ABORT;
6680 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6681 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6682 dict_set_allocator(&ino_dict, NULL, inode_dnode_free, NULL);
6683 dict_set_allocator(&blk_dict, NULL, block_dnode_free, NULL);
6685 pass1b(ctx, block_buf);
6686 pass1c(ctx, block_buf);
6687 pass1d(ctx, block_buf);
6690 * Time to free all of the accumulated data structures that we
6691 * don't need anymore.
6693 dict_free_nodes(&ino_dict);
6694 dict_free_nodes(&blk_dict);
6698 * Scan the inodes looking for inodes that contain duplicate blocks.
6700 struct process_block_struct_1b {
6704 struct ext2_inode *inode;
6705 struct problem_context *pctx;
6708 static void pass1b(e2fsck_t ctx, char *block_buf)
6710 ext2_filsys fs = ctx->fs;
6712 struct ext2_inode inode;
6713 ext2_inode_scan scan;
6714 struct process_block_struct_1b pb;
6715 struct problem_context pctx;
6717 clear_problem_context(&pctx);
6719 if (!(ctx->options & E2F_OPT_PREEN))
6720 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
6721 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
6724 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6725 ctx->flags |= E2F_FLAG_ABORT;
6728 ctx->stashed_inode = &inode;
6731 pctx.str = "pass1b";
6733 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
6734 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
6737 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6738 ctx->flags |= E2F_FLAG_ABORT;
6743 pctx.ino = ctx->stashed_ino = ino;
6744 if ((ino != EXT2_BAD_INO) &&
6745 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
6752 if (ext2fs_inode_has_valid_blocks(&inode) ||
6753 (ino == EXT2_BAD_INO))
6754 pctx.errcode = ext2fs_block_iterate2(fs, ino,
6755 0, block_buf, process_pass1b_block, &pb);
6756 if (inode.i_file_acl)
6757 process_pass1b_block(fs, &inode.i_file_acl,
6758 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6759 if (pb.dup_blocks) {
6760 end_problem_latch(ctx, PR_LATCH_DBLOCK);
6761 if (ino >= EXT2_FIRST_INODE(fs->super) ||
6762 ino == EXT2_ROOT_INO)
6766 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6768 ext2fs_close_inode_scan(scan);
6769 e2fsck_use_inode_shortcuts(ctx, 0);
6772 static int process_pass1b_block(ext2_filsys fs EXT2FS_ATTR((unused)),
6774 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
6775 blk_t ref_blk EXT2FS_ATTR((unused)),
6776 int ref_offset EXT2FS_ATTR((unused)),
6779 struct process_block_struct_1b *p;
6782 if (HOLE_BLKADDR(*block_nr))
6784 p = (struct process_block_struct_1b *) priv_data;
6787 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
6790 /* OK, this is a duplicate block */
6791 if (p->ino != EXT2_BAD_INO) {
6792 p->pctx->blk = *block_nr;
6793 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
6796 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
6798 add_dupe(ctx, p->ino, *block_nr, p->inode);
6804 * Pass 1c: Scan directories for inodes with duplicate blocks. This
6805 * is used so that we can print pathnames when prompting the user for
6808 struct search_dir_struct {
6810 ext2_ino_t first_inode;
6811 ext2_ino_t max_inode;
6814 static int search_dirent_proc(ext2_ino_t dir, int entry,
6815 struct ext2_dir_entry *dirent,
6816 int offset EXT2FS_ATTR((unused)),
6817 int blocksize EXT2FS_ATTR((unused)),
6818 char *buf EXT2FS_ATTR((unused)),
6821 struct search_dir_struct *sd;
6822 struct dup_inode *p;
6825 sd = (struct search_dir_struct *) priv_data;
6827 if (dirent->inode > sd->max_inode)
6828 /* Should abort this inode, but not everything */
6831 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
6832 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
6835 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
6838 p = (struct dup_inode *) dnode_get(n);
6842 return(sd->count ? 0 : DIRENT_ABORT);
6846 static void pass1c(e2fsck_t ctx, char *block_buf)
6848 ext2_filsys fs = ctx->fs;
6849 struct search_dir_struct sd;
6850 struct problem_context pctx;
6852 clear_problem_context(&pctx);
6854 if (!(ctx->options & E2F_OPT_PREEN))
6855 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
6858 * Search through all directories to translate inodes to names
6859 * (by searching for the containing directory for that inode.)
6861 sd.count = dup_inode_count;
6862 sd.first_inode = EXT2_FIRST_INODE(fs->super);
6863 sd.max_inode = fs->super->s_inodes_count;
6864 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
6865 search_dirent_proc, &sd);
6868 static void pass1d(e2fsck_t ctx, char *block_buf)
6870 ext2_filsys fs = ctx->fs;
6871 struct dup_inode *p, *t;
6872 struct dup_block *q;
6873 ext2_ino_t *shared, ino;
6878 struct problem_context pctx;
6883 clear_problem_context(&pctx);
6885 if (!(ctx->options & E2F_OPT_PREEN))
6886 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
6887 e2fsck_read_bitmaps(ctx);
6889 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
6890 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
6891 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
6892 sizeof(ext2_ino_t) * dict_count(&ino_dict),
6893 "Shared inode list");
6894 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
6895 p = (struct dup_inode *) dnode_get(n);
6898 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
6899 if (ino == EXT2_BAD_INO)
6903 * Find all of the inodes which share blocks with this
6904 * one. First we find all of the duplicate blocks
6905 * belonging to this inode, and then search each block
6906 * get the list of inodes, and merge them together.
6908 for (s = p->block_list; s; s = s->next) {
6909 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
6911 continue; /* Should never happen... */
6912 q = (struct dup_block *) dnode_get(m);
6915 if (check_if_fs_block(ctx, s->block)) {
6921 * Add all inodes used by this block to the
6922 * shared[] --- which is a unique list, so
6923 * if an inode is already in shared[], don't
6926 for (r = q->inode_list; r; r = r->next) {
6927 if (r->inode == ino)
6929 for (i = 0; i < shared_len; i++)
6930 if (shared[i] == r->inode)
6932 if (i == shared_len) {
6933 shared[shared_len++] = r->inode;
6939 * Report the inode that we are working on
6941 pctx.inode = &p->inode;
6944 pctx.blkcount = p->num_dupblocks;
6945 pctx.num = meta_data ? shared_len+1 : shared_len;
6946 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
6951 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
6953 for (i = 0; i < shared_len; i++) {
6954 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
6956 continue; /* should never happen */
6957 t = (struct dup_inode *) dnode_get(m);
6959 * Report the inode that we are sharing with
6961 pctx.inode = &t->inode;
6962 pctx.ino = shared[i];
6964 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
6967 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
6970 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
6971 pctx.errcode = clone_file(ctx, ino, p, block_buf);
6973 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
6977 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
6978 delete_file(ctx, ino, p, block_buf);
6980 ext2fs_unmark_valid(fs);
6982 ext2fs_free_mem(&shared);
6986 * Drop the refcount on the dup_block structure, and clear the entry
6987 * in the block_dup_map if appropriate.
6989 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
6992 if (p->num_bad <= 0 ||
6993 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
6994 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
6997 static int delete_file_block(ext2_filsys fs,
6999 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
7000 blk_t ref_block EXT2FS_ATTR((unused)),
7001 int ref_offset EXT2FS_ATTR((unused)),
7004 struct process_block_struct_1b *pb;
7005 struct dup_block *p;
7009 pb = (struct process_block_struct_1b *) priv_data;
7012 if (HOLE_BLKADDR(*block_nr))
7015 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
7016 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
7018 p = (struct dup_block *) dnode_get(n);
7019 decrement_badcount(ctx, *block_nr, p);
7021 com_err("delete_file_block", 0,
7022 _("internal error; can't find dup_blk for %d\n"),
7025 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
7026 ext2fs_block_alloc_stats(fs, *block_nr, -1);
7032 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
7033 struct dup_inode *dp, char* block_buf)
7035 ext2_filsys fs = ctx->fs;
7036 struct process_block_struct_1b pb;
7037 struct ext2_inode inode;
7038 struct problem_context pctx;
7041 clear_problem_context(&pctx);
7042 pctx.ino = pb.ino = ino;
7043 pb.dup_blocks = dp->num_dupblocks;
7045 pctx.str = "delete_file";
7047 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
7048 if (ext2fs_inode_has_valid_blocks(&inode))
7049 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7050 delete_file_block, &pb);
7052 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
7053 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
7054 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
7055 if (ctx->inode_bad_map)
7056 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7057 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
7059 /* Inode may have changed by block_iterate, so reread it */
7060 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
7061 inode.i_links_count = 0;
7062 inode.i_dtime = time(0);
7063 if (inode.i_file_acl &&
7064 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
7066 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
7067 block_buf, -1, &count);
7068 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
7073 pctx.blk = inode.i_file_acl;
7074 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
7077 * If the count is zero, then arrange to have the
7078 * block deleted. If the block is in the block_dup_map,
7079 * also call delete_file_block since it will take care
7080 * of keeping the accounting straight.
7083 ext2fs_test_block_bitmap(ctx->block_dup_map,
7085 delete_file_block(fs, &inode.i_file_acl,
7086 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
7088 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
7091 struct clone_struct {
7098 static int clone_file_block(ext2_filsys fs,
7100 e2_blkcnt_t blockcnt,
7101 blk_t ref_block EXT2FS_ATTR((unused)),
7102 int ref_offset EXT2FS_ATTR((unused)),
7105 struct dup_block *p;
7108 struct clone_struct *cs = (struct clone_struct *) priv_data;
7114 if (HOLE_BLKADDR(*block_nr))
7117 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
7118 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
7120 p = (struct dup_block *) dnode_get(n);
7121 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
7124 cs->errcode = retval;
7127 if (cs->dir && (blockcnt >= 0)) {
7128 retval = ext2fs_set_dir_block(fs->dblist,
7129 cs->dir, new_block, blockcnt);
7131 cs->errcode = retval;
7136 printf("Cloning block %u to %u\n", *block_nr,
7139 retval = io_channel_read_blk(fs->io, *block_nr, 1,
7142 cs->errcode = retval;
7145 retval = io_channel_write_blk(fs->io, new_block, 1,
7148 cs->errcode = retval;
7151 decrement_badcount(ctx, *block_nr, p);
7152 *block_nr = new_block;
7153 ext2fs_mark_block_bitmap(ctx->block_found_map,
7155 ext2fs_mark_block_bitmap(fs->block_map, new_block);
7156 return BLOCK_CHANGED;
7158 com_err("clone_file_block", 0,
7159 _("internal error; can't find dup_blk for %d\n"),
7165 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
7166 struct dup_inode *dp, char* block_buf)
7168 ext2_filsys fs = ctx->fs;
7170 struct clone_struct cs;
7171 struct problem_context pctx;
7174 struct inode_el *ino_el;
7175 struct dup_block *db;
7176 struct dup_inode *di;
7178 clear_problem_context(&pctx);
7182 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
7186 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
7190 pctx.str = "clone_file";
7191 if (ext2fs_inode_has_valid_blocks(&dp->inode))
7192 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7193 clone_file_block, &cs);
7194 ext2fs_mark_bb_dirty(fs);
7196 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
7197 retval = pctx.errcode;
7201 com_err("clone_file", cs.errcode,
7202 _("returned from clone_file_block"));
7203 retval = cs.errcode;
7206 /* The inode may have changed on disk, so we have to re-read it */
7207 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
7208 blk = dp->inode.i_file_acl;
7209 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
7210 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
7212 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
7214 * If we cloned the EA block, find all other inodes
7215 * which refered to that EA block, and modify
7216 * them to point to the new EA block.
7218 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
7219 db = (struct dup_block *) dnode_get(n);
7220 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
7221 if (ino_el->inode == ino)
7223 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
7224 di = (struct dup_inode *) dnode_get(n);
7225 if (di->inode.i_file_acl == blk) {
7226 di->inode.i_file_acl = dp->inode.i_file_acl;
7227 e2fsck_write_inode(ctx, ino_el->inode,
7228 &di->inode, "clone file EA");
7229 decrement_badcount(ctx, blk, db);
7235 ext2fs_free_mem(&cs.buf);
7240 * This routine returns 1 if a block overlaps with one of the superblocks,
7241 * group descriptors, inode bitmaps, or block bitmaps.
7243 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
7245 ext2_filsys fs = ctx->fs;
7249 block = fs->super->s_first_data_block;
7250 for (i = 0; i < fs->group_desc_count; i++) {
7252 /* Check superblocks/block group descriptros */
7253 if (ext2fs_bg_has_super(fs, i)) {
7254 if (test_block >= block &&
7255 (test_block <= block + fs->desc_blocks))
7259 /* Check the inode table */
7260 if ((fs->group_desc[i].bg_inode_table) &&
7261 (test_block >= fs->group_desc[i].bg_inode_table) &&
7262 (test_block < (fs->group_desc[i].bg_inode_table +
7263 fs->inode_blocks_per_group)))
7266 /* Check the bitmap blocks */
7267 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
7268 (test_block == fs->group_desc[i].bg_inode_bitmap))
7271 block += fs->super->s_blocks_per_group;
7276 * pass2.c --- check directory structure
7278 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o
7281 * This file may be redistributed under the terms of the GNU Public
7285 * Pass 2 of e2fsck iterates through all active directory inodes, and
7286 * applies to following tests to each directory entry in the directory
7287 * blocks in the inodes:
7289 * - The length of the directory entry (rec_len) should be at
7290 * least 8 bytes, and no more than the remaining space
7291 * left in the directory block.
7292 * - The length of the name in the directory entry (name_len)
7293 * should be less than (rec_len - 8).
7294 * - The inode number in the directory entry should be within
7296 * - The inode number should refer to a in-use inode.
7297 * - The first entry should be '.', and its inode should be
7298 * the inode of the directory.
7299 * - The second entry should be '..'.
7301 * To minimize disk seek time, the directory blocks are processed in
7302 * sorted order of block numbers.
7304 * Pass 2 also collects the following information:
7305 * - The inode numbers of the subdirectories for each directory.
7307 * Pass 2 relies on the following information from previous passes:
7308 * - The directory information collected in pass 1.
7309 * - The inode_used_map bitmap
7310 * - The inode_bad_map bitmap
7311 * - The inode_dir_map bitmap
7313 * Pass 2 frees the following data structures
7314 * - The inode_bad_map bitmap
7315 * - The inode_reg_map bitmap
7318 /* #define DX_DEBUG */
7321 * Keeps track of how many times an inode is referenced.
7323 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
7324 static int check_dir_block(ext2_filsys fs,
7325 struct ext2_db_entry *dir_blocks_info,
7327 static int allocate_dir_block(e2fsck_t ctx,
7328 struct ext2_db_entry *dir_blocks_info,
7329 char *buf, struct problem_context *pctx);
7330 static int update_dir_block(ext2_filsys fs,
7332 e2_blkcnt_t blockcnt,
7336 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
7337 static int htree_depth(struct dx_dir_info *dx_dir,
7338 struct dx_dirblock_info *dx_db);
7339 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
7341 struct check_dir_struct {
7343 struct problem_context pctx;
7348 void e2fsck_pass2(e2fsck_t ctx)
7350 struct ext2_super_block *sb = ctx->fs->super;
7351 struct problem_context pctx;
7352 ext2_filsys fs = ctx->fs;
7354 #ifdef RESOURCE_TRACK
7355 struct resource_track rtrack;
7357 struct dir_info *dir;
7358 struct check_dir_struct cd;
7359 struct dx_dir_info *dx_dir;
7360 struct dx_dirblock_info *dx_db, *dx_parent;
7366 #ifdef RESOURCE_TRACK
7367 init_resource_track(&rtrack);
7370 clear_problem_context(&cd.pctx);
7373 mtrace_print("Pass 2");
7376 if (!(ctx->options & E2F_OPT_PREEN))
7377 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
7379 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
7380 0, ctx->inode_link_info,
7382 if (cd.pctx.errcode) {
7383 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
7384 ctx->flags |= E2F_FLAG_ABORT;
7387 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
7388 "directory scan buffer");
7391 * Set up the parent pointer for the root directory, if
7392 * present. (If the root directory is not present, we will
7393 * create it in pass 3.)
7395 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
7397 dir->parent = EXT2_ROOT_INO;
7402 cd.max = ext2fs_dblist_count(fs->dblist);
7405 (void) (ctx->progress)(ctx, 2, 0, cd.max);
7407 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
7408 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
7410 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
7412 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7414 if (cd.pctx.errcode) {
7415 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
7416 ctx->flags |= E2F_FLAG_ABORT;
7421 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
7422 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7424 if (dx_dir->numblocks == 0)
7426 clear_problem_context(&pctx);
7428 pctx.dir = dx_dir->ino;
7429 dx_db = dx_dir->dx_block;
7430 if (dx_db->flags & DX_FLAG_REFERENCED)
7431 dx_db->flags |= DX_FLAG_DUP_REF;
7433 dx_db->flags |= DX_FLAG_REFERENCED;
7435 * Find all of the first and last leaf blocks, and
7436 * update their parent's min and max hash values
7438 for (b=0, dx_db = dx_dir->dx_block;
7439 b < dx_dir->numblocks;
7441 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
7442 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
7444 dx_parent = &dx_dir->dx_block[dx_db->parent];
7446 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
7448 if (dx_db->flags & DX_FLAG_FIRST)
7449 dx_parent->min_hash = dx_db->min_hash;
7451 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
7453 if (dx_db->flags & DX_FLAG_LAST)
7454 dx_parent->max_hash = dx_db->max_hash;
7457 for (b=0, dx_db = dx_dir->dx_block;
7458 b < dx_dir->numblocks;
7461 pctx.group = dx_db->parent;
7463 if (!(dx_db->flags & DX_FLAG_FIRST) &&
7464 (dx_db->min_hash < dx_db->node_min_hash)) {
7465 pctx.blk = dx_db->min_hash;
7466 pctx.blk2 = dx_db->node_min_hash;
7467 code = PR_2_HTREE_MIN_HASH;
7468 fix_problem(ctx, code, &pctx);
7471 if (dx_db->type == DX_DIRBLOCK_LEAF) {
7472 depth = htree_depth(dx_dir, dx_db);
7473 if (depth != dx_dir->depth) {
7474 code = PR_2_HTREE_BAD_DEPTH;
7475 fix_problem(ctx, code, &pctx);
7480 * This test doesn't apply for the root block
7484 (dx_db->max_hash > dx_db->node_max_hash)) {
7485 pctx.blk = dx_db->max_hash;
7486 pctx.blk2 = dx_db->node_max_hash;
7487 code = PR_2_HTREE_MAX_HASH;
7488 fix_problem(ctx, code, &pctx);
7491 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
7492 code = PR_2_HTREE_NOTREF;
7493 fix_problem(ctx, code, &pctx);
7495 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
7496 code = PR_2_HTREE_DUPREF;
7497 fix_problem(ctx, code, &pctx);
7503 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
7504 clear_htree(ctx, dx_dir->ino);
7505 dx_dir->numblocks = 0;
7509 ext2fs_free_mem(&buf);
7510 ext2fs_free_dblist(fs->dblist);
7512 if (ctx->inode_bad_map) {
7513 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
7514 ctx->inode_bad_map = 0;
7516 if (ctx->inode_reg_map) {
7517 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
7518 ctx->inode_reg_map = 0;
7521 clear_problem_context(&pctx);
7522 if (ctx->large_files) {
7523 if (!(sb->s_feature_ro_compat &
7524 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
7525 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
7526 sb->s_feature_ro_compat |=
7527 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7528 ext2fs_mark_super_dirty(fs);
7530 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
7531 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
7532 ext2fs_update_dynamic_rev(fs);
7533 ext2fs_mark_super_dirty(fs);
7535 } else if (!ctx->large_files &&
7536 (sb->s_feature_ro_compat &
7537 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
7538 if (fs->flags & EXT2_FLAG_RW) {
7539 sb->s_feature_ro_compat &=
7540 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7541 ext2fs_mark_super_dirty(fs);
7545 #ifdef RESOURCE_TRACK
7546 if (ctx->options & E2F_OPT_TIME2) {
7547 e2fsck_clear_progbar(ctx);
7548 print_resource_track(_("Pass 2"), &rtrack);
7553 #define MAX_DEPTH 32000
7554 static int htree_depth(struct dx_dir_info *dx_dir,
7555 struct dx_dirblock_info *dx_db)
7559 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
7560 dx_db = &dx_dir->dx_block[dx_db->parent];
7566 static int dict_de_cmp(const void *a, const void *b)
7568 const struct ext2_dir_entry *de_a, *de_b;
7571 de_a = (const struct ext2_dir_entry *) a;
7572 a_len = de_a->name_len & 0xFF;
7573 de_b = (const struct ext2_dir_entry *) b;
7574 b_len = de_b->name_len & 0xFF;
7577 return (a_len - b_len);
7579 return strncmp(de_a->name, de_b->name, a_len);
7583 * This is special sort function that makes sure that directory blocks
7584 * with a dirblock of zero are sorted to the beginning of the list.
7585 * This guarantees that the root node of the htree directories are
7586 * processed first, so we know what hash version to use.
7588 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
7590 const struct ext2_db_entry *db_a =
7591 (const struct ext2_db_entry *) a;
7592 const struct ext2_db_entry *db_b =
7593 (const struct ext2_db_entry *) b;
7595 if (db_a->blockcnt && !db_b->blockcnt)
7598 if (!db_a->blockcnt && db_b->blockcnt)
7601 if (db_a->blk != db_b->blk)
7602 return (int) (db_a->blk - db_b->blk);
7604 if (db_a->ino != db_b->ino)
7605 return (int) (db_a->ino - db_b->ino);
7607 return (int) (db_a->blockcnt - db_b->blockcnt);
7612 * Make sure the first entry in the directory is '.', and that the
7613 * directory entry is sane.
7615 static int check_dot(e2fsck_t ctx,
7616 struct ext2_dir_entry *dirent,
7617 ext2_ino_t ino, struct problem_context *pctx)
7619 struct ext2_dir_entry *nextdir;
7626 problem = PR_2_MISSING_DOT;
7627 else if (((dirent->name_len & 0xFF) != 1) ||
7628 (dirent->name[0] != '.'))
7629 problem = PR_2_1ST_NOT_DOT;
7630 else if (dirent->name[1] != '\0')
7631 problem = PR_2_DOT_NULL_TERM;
7634 if (fix_problem(ctx, problem, pctx)) {
7635 if (dirent->rec_len < 12)
7636 dirent->rec_len = 12;
7637 dirent->inode = ino;
7638 dirent->name_len = 1;
7639 dirent->name[0] = '.';
7640 dirent->name[1] = '\0';
7645 if (dirent->inode != ino) {
7646 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
7647 dirent->inode = ino;
7651 if (dirent->rec_len > 12) {
7652 new_len = dirent->rec_len - 12;
7655 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
7656 nextdir = (struct ext2_dir_entry *)
7657 ((char *) dirent + 12);
7658 dirent->rec_len = 12;
7659 nextdir->rec_len = new_len;
7661 nextdir->name_len = 0;
7670 * Make sure the second entry in the directory is '..', and that the
7671 * directory entry is sane. We do not check the inode number of '..'
7672 * here; this gets done in pass 3.
7674 static int check_dotdot(e2fsck_t ctx,
7675 struct ext2_dir_entry *dirent,
7676 struct dir_info *dir, struct problem_context *pctx)
7681 problem = PR_2_MISSING_DOT_DOT;
7682 else if (((dirent->name_len & 0xFF) != 2) ||
7683 (dirent->name[0] != '.') ||
7684 (dirent->name[1] != '.'))
7685 problem = PR_2_2ND_NOT_DOT_DOT;
7686 else if (dirent->name[2] != '\0')
7687 problem = PR_2_DOT_DOT_NULL_TERM;
7690 if (fix_problem(ctx, problem, pctx)) {
7691 if (dirent->rec_len < 12)
7692 dirent->rec_len = 12;
7694 * Note: we don't have the parent inode just
7695 * yet, so we will fill it in with the root
7696 * inode. This will get fixed in pass 3.
7698 dirent->inode = EXT2_ROOT_INO;
7699 dirent->name_len = 2;
7700 dirent->name[0] = '.';
7701 dirent->name[1] = '.';
7702 dirent->name[2] = '\0';
7707 dir->dotdot = dirent->inode;
7712 * Check to make sure a directory entry doesn't contain any illegal
7715 static int check_name(e2fsck_t ctx,
7716 struct ext2_dir_entry *dirent,
7717 ext2_ino_t dir_ino EXT2FS_ATTR((unused)),
7718 struct problem_context *pctx)
7724 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
7725 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
7727 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
7730 dirent->name[i] = '.';
7739 * Check the directory filetype (if present)
7741 static _INLINE_ int check_filetype(e2fsck_t ctx,
7742 struct ext2_dir_entry *dirent,
7743 ext2_ino_t dir_ino EXT2FS_ATTR((unused)),
7744 struct problem_context *pctx)
7746 int filetype = dirent->name_len >> 8;
7747 int should_be = EXT2_FT_UNKNOWN;
7748 struct ext2_inode inode;
7750 if (!(ctx->fs->super->s_feature_incompat &
7751 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
7752 if (filetype == 0 ||
7753 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
7755 dirent->name_len = dirent->name_len & 0xFF;
7759 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
7760 should_be = EXT2_FT_DIR;
7761 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
7763 should_be = EXT2_FT_REG_FILE;
7764 } else if (ctx->inode_bad_map &&
7765 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7769 e2fsck_read_inode(ctx, dirent->inode, &inode,
7771 should_be = ext2_file_type(inode.i_mode);
7773 if (filetype == should_be)
7775 pctx->num = should_be;
7777 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
7781 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
7786 static void parse_int_node(ext2_filsys fs,
7787 struct ext2_db_entry *db,
7788 struct check_dir_struct *cd,
7789 struct dx_dir_info *dx_dir,
7792 struct ext2_dx_root_info *root;
7793 struct ext2_dx_entry *ent;
7794 struct ext2_dx_countlimit *limit;
7795 struct dx_dirblock_info *dx_db;
7796 int i, expect_limit, count;
7798 ext2_dirhash_t min_hash = 0xffffffff;
7799 ext2_dirhash_t max_hash = 0;
7800 ext2_dirhash_t hash = 0, prev_hash;
7802 if (db->blockcnt == 0) {
7803 root = (struct ext2_dx_root_info *) (block_buf + 24);
7806 printf("Root node dump:\n");
7807 printf("\t Reserved zero: %d\n", root->reserved_zero);
7808 printf("\t Hash Version: %d\n", root->hash_version);
7809 printf("\t Info length: %d\n", root->info_length);
7810 printf("\t Indirect levels: %d\n", root->indirect_levels);
7811 printf("\t Flags: %d\n", root->unused_flags);
7814 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
7816 ent = (struct ext2_dx_entry *) (block_buf+8);
7818 limit = (struct ext2_dx_countlimit *) ent;
7821 printf("Number of entries (count): %d\n",
7822 ext2fs_le16_to_cpu(limit->count));
7823 printf("Number of entries (limit): %d\n",
7824 ext2fs_le16_to_cpu(limit->limit));
7827 count = ext2fs_le16_to_cpu(limit->count);
7828 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
7829 sizeof(struct ext2_dx_entry);
7830 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
7831 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
7832 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
7833 goto clear_and_exit;
7835 if (count > expect_limit) {
7836 cd->pctx.num = count;
7837 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
7838 goto clear_and_exit;
7839 count = expect_limit;
7842 for (i=0; i < count; i++) {
7844 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
7846 printf("Entry #%d: Hash 0x%08x, block %d\n", i,
7847 hash, ext2fs_le32_to_cpu(ent[i].block));
7849 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
7850 /* Check to make sure the block is valid */
7851 if (blk > (blk_t) dx_dir->numblocks) {
7853 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
7855 goto clear_and_exit;
7857 if (hash < prev_hash &&
7858 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
7859 goto clear_and_exit;
7860 dx_db = &dx_dir->dx_block[blk];
7861 if (dx_db->flags & DX_FLAG_REFERENCED) {
7862 dx_db->flags |= DX_FLAG_DUP_REF;
7864 dx_db->flags |= DX_FLAG_REFERENCED;
7865 dx_db->parent = db->blockcnt;
7867 if (hash < min_hash)
7869 if (hash > max_hash)
7871 dx_db->node_min_hash = hash;
7873 dx_db->node_max_hash =
7874 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
7876 dx_db->node_max_hash = 0xfffffffe;
7877 dx_db->flags |= DX_FLAG_LAST;
7880 dx_db->flags |= DX_FLAG_FIRST;
7883 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
7884 db->blockcnt, min_hash, max_hash);
7886 dx_db = &dx_dir->dx_block[db->blockcnt];
7887 dx_db->min_hash = min_hash;
7888 dx_db->max_hash = max_hash;
7892 clear_htree(cd->ctx, cd->pctx.ino);
7893 dx_dir->numblocks = 0;
7895 #endif /* ENABLE_HTREE */
7898 * Given a busted directory, try to salvage it somehow.
7901 static void salvage_directory(ext2_filsys fs,
7902 struct ext2_dir_entry *dirent,
7903 struct ext2_dir_entry *prev,
7904 unsigned int *offset)
7906 char *cp = (char *) dirent;
7907 int left = fs->blocksize - *offset - dirent->rec_len;
7908 int name_len = dirent->name_len & 0xFF;
7911 * Special case of directory entry of size 8: copy what's left
7912 * of the directory block up to cover up the invalid hole.
7914 if ((left >= 12) && (dirent->rec_len == 8)) {
7915 memmove(cp, cp+8, left);
7916 memset(cp + left, 0, 8);
7920 * If the directory entry overruns the end of the directory
7921 * block, and the name is small enough to fit, then adjust the
7925 (name_len + 8 <= dirent->rec_len + left) &&
7926 dirent->inode <= fs->super->s_inodes_count &&
7927 strnlen(dirent->name, name_len) == name_len) {
7928 dirent->rec_len += left;
7932 * If the directory entry is a multiple of four, so it is
7933 * valid, let the previous directory entry absorb the invalid
7936 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
7937 prev->rec_len += dirent->rec_len;
7938 *offset += dirent->rec_len;
7942 * Default salvage method --- kill all of the directory
7943 * entries for the rest of the block. We will either try to
7944 * absorb it into the previous directory entry, or create a
7945 * new empty directory entry the rest of the directory block.
7948 prev->rec_len += fs->blocksize - *offset;
7949 *offset = fs->blocksize;
7951 dirent->rec_len = fs->blocksize - *offset;
7952 dirent->name_len = 0;
7957 static int check_dir_block(ext2_filsys fs,
7958 struct ext2_db_entry *db,
7961 struct dir_info *subdir, *dir;
7962 struct dx_dir_info *dx_dir;
7964 struct dx_dirblock_info *dx_db = 0;
7965 #endif /* ENABLE_HTREE */
7966 struct ext2_dir_entry *dirent, *prev;
7967 ext2_dirhash_t hash;
7968 unsigned int offset = 0;
7969 int dir_modified = 0;
7971 blk_t block_nr = db->blk;
7972 ext2_ino_t ino = db->ino;
7974 struct check_dir_struct *cd;
7978 struct ext2_dx_root_info *root;
7979 struct ext2_dx_countlimit *limit;
7980 static dict_t de_dict;
7981 struct problem_context pctx;
7984 cd = (struct check_dir_struct *) priv_data;
7988 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7989 return DIRENT_ABORT;
7991 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
7992 return DIRENT_ABORT;
7995 * Make sure the inode is still in use (could have been
7996 * deleted in the duplicate/bad blocks pass.
7998 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
8002 cd->pctx.blk = block_nr;
8003 cd->pctx.blkcount = db->blockcnt;
8005 cd->pctx.dirent = 0;
8009 if (allocate_dir_block(ctx, db, buf, &cd->pctx))
8019 if (ctx->dirs_to_hash &&
8020 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
8024 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr,
8028 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
8029 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
8030 cd->pctx.errcode = 0; /* We'll handle this ourselves */
8031 if (cd->pctx.errcode) {
8032 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
8033 ctx->flags |= E2F_FLAG_ABORT;
8034 return DIRENT_ABORT;
8036 memset(buf, 0, fs->blocksize);
8039 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
8040 if (dx_dir && dx_dir->numblocks) {
8041 if (db->blockcnt >= dx_dir->numblocks) {
8042 printf("XXX should never happen!!!\n");
8045 dx_db = &dx_dir->dx_block[db->blockcnt];
8046 dx_db->type = DX_DIRBLOCK_LEAF;
8047 dx_db->phys = block_nr;
8048 dx_db->min_hash = ~0;
8049 dx_db->max_hash = 0;
8051 dirent = (struct ext2_dir_entry *) buf;
8052 limit = (struct ext2_dx_countlimit *) (buf+8);
8053 if (db->blockcnt == 0) {
8054 root = (struct ext2_dx_root_info *) (buf + 24);
8055 dx_db->type = DX_DIRBLOCK_ROOT;
8056 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
8057 if ((root->reserved_zero ||
8058 root->info_length < 8 ||
8059 root->indirect_levels > 1) &&
8060 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
8061 clear_htree(ctx, ino);
8062 dx_dir->numblocks = 0;
8065 dx_dir->hashversion = root->hash_version;
8066 dx_dir->depth = root->indirect_levels + 1;
8067 } else if ((dirent->inode == 0) &&
8068 (dirent->rec_len == fs->blocksize) &&
8069 (dirent->name_len == 0) &&
8070 (ext2fs_le16_to_cpu(limit->limit) ==
8071 ((fs->blocksize-8) /
8072 sizeof(struct ext2_dx_entry))))
8073 dx_db->type = DX_DIRBLOCK_NODE;
8075 #endif /* ENABLE_HTREE */
8077 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
8081 dirent = (struct ext2_dir_entry *) (buf + offset);
8082 cd->pctx.dirent = dirent;
8083 cd->pctx.num = offset;
8084 if (((offset + dirent->rec_len) > fs->blocksize) ||
8085 (dirent->rec_len < 12) ||
8086 ((dirent->rec_len % 4) != 0) ||
8087 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
8088 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
8089 salvage_directory(fs, dirent, prev, &offset);
8093 goto abort_free_dict;
8095 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
8096 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
8097 dirent->name_len = EXT2_NAME_LEN;
8102 if (dot_state == 0) {
8103 if (check_dot(ctx, dirent, ino, &cd->pctx))
8105 } else if (dot_state == 1) {
8106 dir = e2fsck_get_dir_info(ctx, ino);
8108 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
8109 goto abort_free_dict;
8111 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
8113 } else if (dirent->inode == ino) {
8114 problem = PR_2_LINK_DOT;
8115 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
8125 * Make sure the inode listed is a legal one.
8127 if (((dirent->inode != EXT2_ROOT_INO) &&
8128 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
8129 (dirent->inode > fs->super->s_inodes_count)) {
8130 problem = PR_2_BAD_INO;
8131 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
8134 * If the inode is unused, offer to clear it.
8136 problem = PR_2_UNUSED_INODE;
8137 } else if (ctx->inode_bb_map &&
8138 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
8141 * If the inode is in a bad block, offer to
8144 problem = PR_2_BB_INODE;
8145 } else if ((dot_state > 1) &&
8146 ((dirent->name_len & 0xFF) == 1) &&
8147 (dirent->name[0] == '.')) {
8149 * If there's a '.' entry in anything other
8150 * than the first directory entry, it's a
8151 * duplicate entry that should be removed.
8153 problem = PR_2_DUP_DOT;
8154 } else if ((dot_state > 1) &&
8155 ((dirent->name_len & 0xFF) == 2) &&
8156 (dirent->name[0] == '.') &&
8157 (dirent->name[1] == '.')) {
8159 * If there's a '..' entry in anything other
8160 * than the second directory entry, it's a
8161 * duplicate entry that should be removed.
8163 problem = PR_2_DUP_DOT_DOT;
8164 } else if ((dot_state > 1) &&
8165 (dirent->inode == EXT2_ROOT_INO)) {
8167 * Don't allow links to the root directory.
8168 * We check this specially to make sure we
8169 * catch this error case even if the root
8170 * directory hasn't been created yet.
8172 problem = PR_2_LINK_ROOT;
8173 } else if ((dot_state > 1) &&
8174 (dirent->name_len & 0xFF) == 0) {
8176 * Don't allow zero-length directory names.
8178 problem = PR_2_NULL_NAME;
8182 if (fix_problem(ctx, problem, &cd->pctx)) {
8187 ext2fs_unmark_valid(fs);
8188 if (problem == PR_2_BAD_INO)
8194 * If the inode was marked as having bad fields in
8195 * pass1, process it and offer to fix/clear it.
8196 * (We wait until now so that we can display the
8197 * pathname to the user.)
8199 if (ctx->inode_bad_map &&
8200 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
8202 if (e2fsck_process_bad_inode(ctx, ino,
8204 buf + fs->blocksize)) {
8209 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8210 return DIRENT_ABORT;
8213 if (check_name(ctx, dirent, ino, &cd->pctx))
8216 if (check_filetype(ctx, dirent, ino, &cd->pctx))
8221 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
8222 (dirent->name_len & 0xFF),
8223 fs->super->s_hash_seed, &hash, 0);
8224 if (hash < dx_db->min_hash)
8225 dx_db->min_hash = hash;
8226 if (hash > dx_db->max_hash)
8227 dx_db->max_hash = hash;
8232 * If this is a directory, then mark its parent in its
8233 * dir_info structure. If the parent field is already
8234 * filled in, then this directory has more than one
8235 * hard link. We assume the first link is correct,
8236 * and ask the user if he/she wants to clear this one.
8238 if ((dot_state > 1) &&
8239 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8241 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
8243 cd->pctx.ino = dirent->inode;
8244 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
8245 goto abort_free_dict;
8247 if (subdir->parent) {
8248 cd->pctx.ino2 = subdir->parent;
8249 if (fix_problem(ctx, PR_2_LINK_DIR,
8257 subdir->parent = ino;
8262 } else if (dict_lookup(&de_dict, dirent)) {
8263 clear_problem_context(&pctx);
8265 pctx.dirent = dirent;
8266 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
8267 if (!ctx->dirs_to_hash)
8268 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
8269 if (ctx->dirs_to_hash)
8270 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8273 dict_alloc_insert(&de_dict, dirent, dirent);
8275 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
8278 ctx->fs_links_count++;
8279 ctx->fs_total_count++;
8282 offset += dirent->rec_len;
8284 } while (offset < fs->blocksize);
8291 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
8292 db->blockcnt, dx_db->type,
8293 dx_db->min_hash, dx_db->max_hash);
8295 cd->pctx.dir = cd->pctx.ino;
8296 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
8297 (dx_db->type == DX_DIRBLOCK_NODE))
8298 parse_int_node(fs, db, cd, dx_dir, buf);
8300 #endif /* ENABLE_HTREE */
8301 if (offset != fs->blocksize) {
8302 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
8303 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
8304 dirent->rec_len = cd->pctx.num;
8309 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
8310 if (cd->pctx.errcode) {
8311 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
8313 goto abort_free_dict;
8315 ext2fs_mark_changed(fs);
8317 dict_free_nodes(&de_dict);
8320 dict_free_nodes(&de_dict);
8321 ctx->flags |= E2F_FLAG_ABORT;
8322 return DIRENT_ABORT;
8326 * This function is called to deallocate a block, and is an interator
8327 * functioned called by deallocate inode via ext2fs_iterate_block().
8329 static int deallocate_inode_block(ext2_filsys fs,
8331 e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
8332 blk_t ref_block EXT2FS_ATTR((unused)),
8333 int ref_offset EXT2FS_ATTR((unused)),
8336 e2fsck_t ctx = (e2fsck_t) priv_data;
8338 if (HOLE_BLKADDR(*block_nr))
8340 if ((*block_nr < fs->super->s_first_data_block) ||
8341 (*block_nr >= fs->super->s_blocks_count))
8343 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
8344 ext2fs_block_alloc_stats(fs, *block_nr, -1);
8349 * This fuction deallocates an inode
8351 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
8353 ext2_filsys fs = ctx->fs;
8354 struct ext2_inode inode;
8355 struct problem_context pctx;
8358 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
8359 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
8360 inode.i_links_count = 0;
8361 inode.i_dtime = time(0);
8362 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
8363 clear_problem_context(&pctx);
8367 * Fix up the bitmaps...
8369 e2fsck_read_bitmaps(ctx);
8370 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
8371 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
8372 if (ctx->inode_bad_map)
8373 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8374 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
8376 if (inode.i_file_acl &&
8377 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
8378 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
8379 block_buf, -1, &count);
8380 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
8385 pctx.blk = inode.i_file_acl;
8386 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
8387 ctx->flags |= E2F_FLAG_ABORT;
8391 ext2fs_unmark_block_bitmap(ctx->block_found_map,
8393 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
8395 inode.i_file_acl = 0;
8398 if (!ext2fs_inode_has_valid_blocks(&inode))
8401 if (LINUX_S_ISREG(inode.i_mode) &&
8402 (inode.i_size_high || inode.i_size & 0x80000000UL))
8405 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
8406 deallocate_inode_block, ctx);
8408 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
8409 ctx->flags |= E2F_FLAG_ABORT;
8415 * This fuction clears the htree flag on an inode
8417 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
8419 struct ext2_inode inode;
8421 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
8422 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
8423 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
8424 if (ctx->dirs_to_hash)
8425 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8429 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
8430 ext2_ino_t ino, char *buf)
8432 ext2_filsys fs = ctx->fs;
8433 struct ext2_inode inode;
8434 int inode_modified = 0;
8436 unsigned char *frag, *fsize;
8437 struct problem_context pctx;
8440 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
8442 clear_problem_context(&pctx);
8445 pctx.inode = &inode;
8447 if (inode.i_file_acl &&
8448 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
8449 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
8450 inode.i_file_acl = 0;
8451 #ifdef EXT2FS_ENABLE_SWAPFS
8453 * This is a special kludge to deal with long symlinks
8454 * on big endian systems. i_blocks had already been
8455 * decremented earlier in pass 1, but since i_file_acl
8456 * hadn't yet been cleared, ext2fs_read_inode()
8457 * assumed that the file was short symlink and would
8458 * not have byte swapped i_block[0]. Hence, we have
8459 * to byte-swap it here.
8461 if (LINUX_S_ISLNK(inode.i_mode) &&
8462 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
8463 (inode.i_blocks == fs->blocksize >> 9))
8464 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
8470 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
8471 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
8472 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
8473 !(LINUX_S_ISSOCK(inode.i_mode)))
8474 problem = PR_2_BAD_MODE;
8475 else if (LINUX_S_ISCHR(inode.i_mode)
8476 && !e2fsck_pass1_check_device_inode(fs, &inode))
8477 problem = PR_2_BAD_CHAR_DEV;
8478 else if (LINUX_S_ISBLK(inode.i_mode)
8479 && !e2fsck_pass1_check_device_inode(fs, &inode))
8480 problem = PR_2_BAD_BLOCK_DEV;
8481 else if (LINUX_S_ISFIFO(inode.i_mode)
8482 && !e2fsck_pass1_check_device_inode(fs, &inode))
8483 problem = PR_2_BAD_FIFO;
8484 else if (LINUX_S_ISSOCK(inode.i_mode)
8485 && !e2fsck_pass1_check_device_inode(fs, &inode))
8486 problem = PR_2_BAD_SOCKET;
8487 else if (LINUX_S_ISLNK(inode.i_mode)
8488 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
8489 problem = PR_2_INVALID_SYMLINK;
8493 if (fix_problem(ctx, problem, &pctx)) {
8494 deallocate_inode(ctx, ino, 0);
8495 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8503 if (inode.i_faddr) {
8504 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
8511 switch (fs->super->s_creator_os) {
8513 frag = &inode.osd2.linux2.l_i_frag;
8514 fsize = &inode.osd2.linux2.l_i_fsize;
8517 frag = &inode.osd2.hurd2.h_i_frag;
8518 fsize = &inode.osd2.hurd2.h_i_fsize;
8521 frag = &inode.osd2.masix2.m_i_frag;
8522 fsize = &inode.osd2.masix2.m_i_fsize;
8527 if (frag && *frag) {
8529 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
8536 if (fsize && *fsize) {
8538 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
8546 if (inode.i_file_acl &&
8547 ((inode.i_file_acl < fs->super->s_first_data_block) ||
8548 (inode.i_file_acl >= fs->super->s_blocks_count))) {
8549 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
8550 inode.i_file_acl = 0;
8555 if (inode.i_dir_acl &&
8556 LINUX_S_ISDIR(inode.i_mode)) {
8557 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
8558 inode.i_dir_acl = 0;
8565 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
8567 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8573 * allocate_dir_block --- this function allocates a new directory
8574 * block for a particular inode; this is done if a directory has
8575 * a "hole" in it, or if a directory has a illegal block number
8576 * that was zeroed out and now needs to be replaced.
8578 static int allocate_dir_block(e2fsck_t ctx,
8579 struct ext2_db_entry *db,
8580 char *buf EXT2FS_ATTR((unused)),
8581 struct problem_context *pctx)
8583 ext2_filsys fs = ctx->fs;
8586 struct ext2_inode inode;
8588 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
8592 * Read the inode and block bitmaps in; we'll be messing with
8595 e2fsck_read_bitmaps(ctx);
8598 * First, find a free block
8600 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8601 if (pctx->errcode) {
8602 pctx->str = "ext2fs_new_block";
8603 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8606 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8607 ext2fs_mark_block_bitmap(fs->block_map, blk);
8608 ext2fs_mark_bb_dirty(fs);
8611 * Now let's create the actual data block for the inode
8614 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
8616 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
8617 EXT2_ROOT_INO, &block);
8619 if (pctx->errcode) {
8620 pctx->str = "ext2fs_new_dir_block";
8621 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8625 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
8626 ext2fs_free_mem(&block);
8627 if (pctx->errcode) {
8628 pctx->str = "ext2fs_write_dir_block";
8629 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8634 * Update the inode block count
8636 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
8637 inode.i_blocks += fs->blocksize / 512;
8638 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
8639 inode.i_size = (db->blockcnt+1) * fs->blocksize;
8640 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
8643 * Finally, update the block pointers for the inode
8646 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
8647 0, update_dir_block, db);
8648 if (pctx->errcode) {
8649 pctx->str = "ext2fs_block_iterate";
8650 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8658 * This is a helper function for allocate_dir_block().
8660 static int update_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
8662 e2_blkcnt_t blockcnt,
8663 blk_t ref_block EXT2FS_ATTR((unused)),
8664 int ref_offset EXT2FS_ATTR((unused)),
8667 struct ext2_db_entry *db;
8669 db = (struct ext2_db_entry *) priv_data;
8670 if (db->blockcnt == (int) blockcnt) {
8671 *block_nr = db->blk;
8672 return BLOCK_CHANGED;
8677 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
8679 * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
8682 * This file may be redistributed under the terms of the GNU Public
8686 * Pass #3 assures that all directories are connected to the
8687 * filesystem tree, using the following algorithm:
8689 * First, the root directory is checked to make sure it exists; if
8690 * not, e2fsck will offer to create a new one. It is then marked as
8693 * Then, pass3 interates over all directory inodes; for each directory
8694 * it attempts to trace up the filesystem tree, using dirinfo.parent
8695 * until it reaches a directory which has been marked "done". If it
8696 * can not do so, then the directory must be disconnected, and e2fsck
8697 * will offer to reconnect it to /lost+found. While it is chasing
8698 * parent pointers up the filesystem tree, if pass3 sees a directory
8699 * twice, then it has detected a filesystem loop, and it will again
8700 * offer to reconnect the directory to /lost+found in to break the
8703 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
8704 * reconnect inodes to /lost+found; this subroutine is also used by
8705 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
8706 * is responsible for creating /lost+found if it does not exist.
8708 * Pass 3 frees the following data structures:
8709 * - The dirinfo directory information cache.
8712 static void check_root(e2fsck_t ctx);
8713 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8714 struct problem_context *pctx);
8715 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
8717 static ext2fs_inode_bitmap inode_loop_detect = 0;
8718 static ext2fs_inode_bitmap inode_done_map = 0;
8720 void e2fsck_pass3(e2fsck_t ctx)
8722 ext2_filsys fs = ctx->fs;
8724 #ifdef RESOURCE_TRACK
8725 struct resource_track rtrack;
8727 struct problem_context pctx;
8728 struct dir_info *dir;
8729 unsigned long maxdirs, count;
8731 #ifdef RESOURCE_TRACK
8732 init_resource_track(&rtrack);
8735 clear_problem_context(&pctx);
8738 mtrace_print("Pass 3");
8741 if (!(ctx->options & E2F_OPT_PREEN))
8742 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
8745 * Allocate some bitmaps to do loop detection.
8747 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
8751 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
8752 ctx->flags |= E2F_FLAG_ABORT;
8755 #ifdef RESOURCE_TRACK
8756 if (ctx->options & E2F_OPT_TIME) {
8757 e2fsck_clear_progbar(ctx);
8758 print_resource_track(_("Peak memory"), &ctx->global_rtrack);
8763 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8766 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
8768 maxdirs = e2fsck_get_num_dirinfo(ctx);
8772 if ((ctx->progress)(ctx, 3, 0, maxdirs))
8775 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
8776 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8778 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
8780 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
8781 if (check_directory(ctx, dir, &pctx))
8786 * Force the creation of /lost+found if not present
8788 if ((ctx->flags & E2F_OPT_READONLY) == 0)
8789 e2fsck_get_lost_and_found(ctx, 1);
8792 * If there are any directories that need to be indexed or
8793 * optimized, do it here.
8795 e2fsck_rehash_directories(ctx);
8798 e2fsck_free_dir_info(ctx);
8799 if (inode_loop_detect) {
8800 ext2fs_free_inode_bitmap(inode_loop_detect);
8801 inode_loop_detect = 0;
8803 if (inode_done_map) {
8804 ext2fs_free_inode_bitmap(inode_done_map);
8808 #ifdef RESOURCE_TRACK
8809 if (ctx->options & E2F_OPT_TIME2) {
8810 e2fsck_clear_progbar(ctx);
8811 print_resource_track(_("Pass 3"), &rtrack);
8817 * This makes sure the root inode is present; if not, we ask if the
8818 * user wants us to create it. Not creating it is a fatal error.
8820 static void check_root(e2fsck_t ctx)
8822 ext2_filsys fs = ctx->fs;
8824 struct ext2_inode inode;
8826 struct problem_context pctx;
8828 clear_problem_context(&pctx);
8830 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
8832 * If the root inode is not a directory, die here. The
8833 * user must have answered 'no' in pass1 when we
8834 * offered to clear it.
8836 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8838 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
8839 ctx->flags |= E2F_FLAG_ABORT;
8844 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
8845 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
8846 ctx->flags |= E2F_FLAG_ABORT;
8850 e2fsck_read_bitmaps(ctx);
8853 * First, find a free block
8855 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8857 pctx.str = "ext2fs_new_block";
8858 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8859 ctx->flags |= E2F_FLAG_ABORT;
8862 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8863 ext2fs_mark_block_bitmap(fs->block_map, blk);
8864 ext2fs_mark_bb_dirty(fs);
8867 * Now let's create the actual data block for the inode
8869 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
8872 pctx.str = "ext2fs_new_dir_block";
8873 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8874 ctx->flags |= E2F_FLAG_ABORT;
8878 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
8880 pctx.str = "ext2fs_write_dir_block";
8881 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8882 ctx->flags |= E2F_FLAG_ABORT;
8885 ext2fs_free_mem(&block);
8888 * Set up the inode structure
8890 memset(&inode, 0, sizeof(inode));
8891 inode.i_mode = 040755;
8892 inode.i_size = fs->blocksize;
8893 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8894 inode.i_links_count = 2;
8895 inode.i_blocks = fs->blocksize / 512;
8896 inode.i_block[0] = blk;
8899 * Write out the inode.
8901 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
8903 pctx.str = "ext2fs_write_inode";
8904 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8905 ctx->flags |= E2F_FLAG_ABORT;
8910 * Miscellaneous bookkeeping...
8912 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
8913 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
8914 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
8916 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
8917 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
8918 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
8919 ext2fs_mark_ib_dirty(fs);
8923 * This subroutine is responsible for making sure that a particular
8924 * directory is connected to the root; if it isn't we trace it up as
8925 * far as we can go, and then offer to connect the resulting parent to
8926 * the lost+found. We have to do loop detection; if we ever discover
8927 * a loop, we treat that as a disconnected directory and offer to
8928 * reparent it to lost+found.
8930 * However, loop detection is expensive, because for very large
8931 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
8932 * is non-trivial. Loops in filesystems are also a rare error case,
8933 * and we shouldn't optimize for error cases. So we try two passes of
8934 * the algorithm. The first time, we ignore loop detection and merely
8935 * increment a counter; if the counter exceeds some extreme threshold,
8936 * then we try again with the loop detection bitmap enabled.
8938 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8939 struct problem_context *pctx)
8941 ext2_filsys fs = ctx->fs;
8942 struct dir_info *p = dir;
8943 int loop_pass = 0, parent_count = 0;
8950 * Mark this inode as being "done"; by the time we
8951 * return from this function, the inode we either be
8952 * verified as being connected to the directory tree,
8953 * or we will have offered to reconnect this to
8956 * If it was marked done already, then we've reached a
8957 * parent we've already checked.
8959 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
8963 * If this directory doesn't have a parent, or we've
8964 * seen the parent once already, then offer to
8965 * reparent it to lost+found
8969 (ext2fs_test_inode_bitmap(inode_loop_detect,
8972 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
8973 if (e2fsck_reconnect_file(ctx, pctx->ino))
8974 ext2fs_unmark_valid(fs);
8976 p = e2fsck_get_dir_info(ctx, pctx->ino);
8977 p->parent = ctx->lost_and_found;
8978 fix_dotdot(ctx, p, ctx->lost_and_found);
8983 p = e2fsck_get_dir_info(ctx, p->parent);
8985 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
8989 ext2fs_mark_inode_bitmap(inode_loop_detect,
8991 } else if (parent_count++ > 2048) {
8993 * If we've run into a path depth that's
8994 * greater than 2048, try again with the inode
8995 * loop bitmap turned on and start from the
8999 if (inode_loop_detect)
9000 ext2fs_clear_inode_bitmap(inode_loop_detect);
9002 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
9003 if (pctx->errcode) {
9006 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
9007 ctx->flags |= E2F_FLAG_ABORT;
9016 * Make sure that .. and the parent directory are the same;
9017 * offer to fix it if not.
9019 if (dir->parent != dir->dotdot) {
9020 pctx->ino = dir->ino;
9021 pctx->ino2 = dir->dotdot;
9022 pctx->dir = dir->parent;
9023 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
9024 fix_dotdot(ctx, dir, dir->parent);
9030 * This routine gets the lost_and_found inode, making it a directory
9033 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
9035 ext2_filsys fs = ctx->fs;
9039 struct ext2_inode inode;
9041 static const char name[] = "lost+found";
9042 struct problem_context pctx;
9043 struct dir_info *dirinfo;
9045 if (ctx->lost_and_found)
9046 return ctx->lost_and_found;
9048 clear_problem_context(&pctx);
9050 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
9051 sizeof(name)-1, 0, &ino);
9055 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
9056 ctx->lost_and_found = ino;
9060 /* Lost+found isn't a directory! */
9064 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
9067 /* OK, unlink the old /lost+found file. */
9068 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
9070 pctx.str = "ext2fs_unlink";
9071 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9074 dirinfo = e2fsck_get_dir_info(ctx, ino);
9076 dirinfo->parent = 0;
9077 e2fsck_adjust_inode_count(ctx, ino, -1);
9078 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
9079 pctx.errcode = retval;
9080 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
9082 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
9086 * Read the inode and block bitmaps in; we'll be messing with
9089 e2fsck_read_bitmaps(ctx);
9092 * First, find a free block
9094 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
9096 pctx.errcode = retval;
9097 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
9100 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
9101 ext2fs_block_alloc_stats(fs, blk, +1);
9104 * Next find a free inode.
9106 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
9107 ctx->inode_used_map, &ino);
9109 pctx.errcode = retval;
9110 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
9113 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
9114 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
9115 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
9118 * Now let's create the actual data block for the inode
9120 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
9122 pctx.errcode = retval;
9123 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
9127 retval = ext2fs_write_dir_block(fs, blk, block);
9128 ext2fs_free_mem(&block);
9130 pctx.errcode = retval;
9131 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
9136 * Set up the inode structure
9138 memset(&inode, 0, sizeof(inode));
9139 inode.i_mode = 040700;
9140 inode.i_size = fs->blocksize;
9141 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
9142 inode.i_links_count = 2;
9143 inode.i_blocks = fs->blocksize / 512;
9144 inode.i_block[0] = blk;
9147 * Next, write out the inode.
9149 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
9151 pctx.str = "ext2fs_write_inode";
9152 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9156 * Finally, create the directory link
9158 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
9160 pctx.str = "ext2fs_link";
9161 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9166 * Miscellaneous bookkeeping that needs to be kept straight.
9168 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
9169 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
9170 ext2fs_icount_store(ctx->inode_count, ino, 2);
9171 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
9172 ctx->lost_and_found = ino;
9174 printf("/lost+found created; inode #%lu\n", ino);
9180 * This routine will connect a file to lost+found
9182 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
9184 ext2_filsys fs = ctx->fs;
9187 struct problem_context pctx;
9188 struct ext2_inode inode;
9191 clear_problem_context(&pctx);
9194 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
9195 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
9196 ctx->bad_lost_and_found++;
9198 if (ctx->bad_lost_and_found) {
9199 fix_problem(ctx, PR_3_NO_LPF, &pctx);
9203 sprintf(name, "#%u", ino);
9204 if (ext2fs_read_inode(fs, ino, &inode) == 0)
9205 file_type = ext2_file_type(inode.i_mode);
9206 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
9207 if (retval == EXT2_ET_DIR_NO_SPACE) {
9208 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
9210 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
9213 pctx.errcode = retval;
9214 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
9217 retval = ext2fs_link(fs, ctx->lost_and_found, name,
9221 pctx.errcode = retval;
9222 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
9225 e2fsck_adjust_inode_count(ctx, ino, 1);
9231 * Utility routine to adjust the inode counts on an inode.
9233 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
9235 ext2_filsys fs = ctx->fs;
9237 struct ext2_inode inode;
9242 retval = ext2fs_read_inode(fs, ino, &inode);
9247 printf("Adjusting link count for inode %lu by %d (from %d)\n", ino, adj,
9248 inode.i_links_count);
9252 ext2fs_icount_increment(ctx->inode_count, ino, 0);
9253 if (inode.i_links_count == (__u16) ~0)
9255 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
9256 inode.i_links_count++;
9257 } else if (adj == -1) {
9258 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
9259 if (inode.i_links_count == 0)
9261 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
9262 inode.i_links_count--;
9265 retval = ext2fs_write_inode(fs, ino, &inode);
9273 * Fix parent --- this routine fixes up the parent of a directory.
9275 struct fix_dotdot_struct {
9282 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
9283 int offset EXT2FS_ATTR((unused)),
9284 int blocksize EXT2FS_ATTR((unused)),
9285 char *buf EXT2FS_ATTR((unused)),
9288 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
9290 struct problem_context pctx;
9292 if ((dirent->name_len & 0xFF) != 2)
9294 if (strncmp(dirent->name, "..", 2))
9297 clear_problem_context(&pctx);
9299 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
9301 pctx.errcode = retval;
9302 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9304 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
9306 pctx.errcode = retval;
9307 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9309 dirent->inode = fp->parent;
9312 return DIRENT_ABORT | DIRENT_CHANGED;
9315 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
9317 ext2_filsys fs = ctx->fs;
9319 struct fix_dotdot_struct fp;
9320 struct problem_context pctx;
9328 printf("Fixing '..' of inode %lu to be %lu...\n", dir->ino, parent);
9331 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
9332 0, fix_dotdot_proc, &fp);
9333 if (retval || !fp.done) {
9334 clear_problem_context(&pctx);
9335 pctx.ino = dir->ino;
9336 pctx.errcode = retval;
9337 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
9338 PR_3_FIX_PARENT_NOFIND, &pctx);
9339 ext2fs_unmark_valid(fs);
9341 dir->dotdot = parent;
9347 * These routines are responsible for expanding a /lost+found if it is
9351 struct expand_dir_struct {
9353 int guaranteed_size;
9360 static int expand_dir_proc(ext2_filsys fs,
9362 e2_blkcnt_t blockcnt,
9363 blk_t ref_block EXT2FS_ATTR((unused)),
9364 int ref_offset EXT2FS_ATTR((unused)),
9367 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
9369 static blk_t last_blk = 0;
9376 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
9380 es->last_block = blockcnt;
9382 last_blk = *blocknr;
9385 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
9392 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
9398 retval = ext2fs_write_dir_block(fs, new_blk, block);
9400 retval = ext2fs_get_mem(fs->blocksize, &block);
9405 memset(block, 0, fs->blocksize);
9406 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
9412 ext2fs_free_mem(&block);
9414 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
9415 ext2fs_block_alloc_stats(fs, new_blk, +1);
9419 return (BLOCK_CHANGED | BLOCK_ABORT);
9421 return BLOCK_CHANGED;
9424 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
9425 int num, int guaranteed_size)
9427 ext2_filsys fs = ctx->fs;
9429 struct expand_dir_struct es;
9430 struct ext2_inode inode;
9432 if (!(fs->flags & EXT2_FLAG_RW))
9433 return EXT2_ET_RO_FILSYS;
9436 * Read the inode and block bitmaps in; we'll be messing with
9439 e2fsck_read_bitmaps(ctx);
9441 retval = ext2fs_check_directory(fs, dir);
9446 es.guaranteed_size = guaranteed_size;
9452 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
9453 0, expand_dir_proc, &es);
9459 * Update the size and block count fields in the inode.
9461 retval = ext2fs_read_inode(fs, dir, &inode);
9465 inode.i_size = (es.last_block + 1) * fs->blocksize;
9466 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
9468 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
9474 * pass4.c -- pass #4 of e2fsck: Check reference counts
9476 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
9479 * This file may be redistributed under the terms of the GNU Public
9483 * Pass 4 frees the following data structures:
9484 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
9485 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
9489 * This routine is called when an inode is not connected to the
9492 * This subroutine returns 1 then the caller shouldn't bother with the
9493 * rest of the pass 4 tests.
9495 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
9497 ext2_filsys fs = ctx->fs;
9498 struct ext2_inode inode;
9499 struct problem_context pctx;
9501 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
9502 clear_problem_context(&pctx);
9504 pctx.inode = &inode;
9507 * Offer to delete any zero-length files that does not have
9508 * blocks. If there is an EA block, it might have useful
9509 * information, so we won't prompt to delete it, but let it be
9510 * reconnected to lost+found.
9512 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
9513 LINUX_S_ISDIR(inode.i_mode))) {
9514 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
9515 ext2fs_icount_store(ctx->inode_link_info, i, 0);
9516 inode.i_links_count = 0;
9517 inode.i_dtime = time(0);
9518 e2fsck_write_inode(ctx, i, &inode,
9519 "disconnect_inode");
9521 * Fix up the bitmaps...
9523 e2fsck_read_bitmaps(ctx);
9524 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
9525 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
9526 ext2fs_inode_alloc_stats2(fs, i, -1,
9527 LINUX_S_ISDIR(inode.i_mode));
9533 * Prompt to reconnect.
9535 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
9536 if (e2fsck_reconnect_file(ctx, i))
9537 ext2fs_unmark_valid(fs);
9540 * If we don't attach the inode, then skip the
9541 * i_links_test since there's no point in trying to
9542 * force i_links_count to zero.
9544 ext2fs_unmark_valid(fs);
9551 void e2fsck_pass4(e2fsck_t ctx)
9553 ext2_filsys fs = ctx->fs;
9555 struct ext2_inode inode;
9556 #ifdef RESOURCE_TRACK
9557 struct resource_track rtrack;
9559 struct problem_context pctx;
9560 __u16 link_count, link_counted;
9562 int group, maxgroup;
9564 #ifdef RESOURCE_TRACK
9565 init_resource_track(&rtrack);
9569 mtrace_print("Pass 4");
9572 clear_problem_context(&pctx);
9574 if (!(ctx->options & E2F_OPT_PREEN))
9575 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
9578 maxgroup = fs->group_desc_count;
9580 if ((ctx->progress)(ctx, 4, 0, maxgroup))
9583 for (i=1; i <= fs->super->s_inodes_count; i++) {
9584 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9586 if ((i % fs->super->s_inodes_per_group) == 0) {
9589 if ((ctx->progress)(ctx, 4, group, maxgroup))
9592 if (i == EXT2_BAD_INO ||
9593 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
9595 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
9596 (ctx->inode_imagic_map &&
9597 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
9598 (ctx->inode_bb_map &&
9599 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
9601 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
9602 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
9603 if (link_counted == 0) {
9605 buf = e2fsck_allocate_memory(ctx,
9606 fs->blocksize, "bad_inode buffer");
9607 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
9609 if (disconnect_inode(ctx, i))
9611 ext2fs_icount_fetch(ctx->inode_link_info, i,
9613 ext2fs_icount_fetch(ctx->inode_count, i,
9616 if (link_counted != link_count) {
9617 e2fsck_read_inode(ctx, i, &inode, "pass4");
9619 pctx.inode = &inode;
9620 if (link_count != inode.i_links_count) {
9621 pctx.num = link_count;
9623 PR_4_INCONSISTENT_COUNT, &pctx);
9625 pctx.num = link_counted;
9626 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
9627 inode.i_links_count = link_counted;
9628 e2fsck_write_inode(ctx, i, &inode, "pass4");
9632 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
9633 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
9634 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
9635 ctx->inode_bb_map = 0;
9636 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
9637 ctx->inode_imagic_map = 0;
9639 ext2fs_free_mem(&buf);
9640 #ifdef RESOURCE_TRACK
9641 if (ctx->options & E2F_OPT_TIME2) {
9642 e2fsck_clear_progbar(ctx);
9643 print_resource_track(_("Pass 4"), &rtrack);
9649 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
9651 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
9654 * This file may be redistributed under the terms of the GNU Public
9660 static void check_block_bitmaps(e2fsck_t ctx);
9661 static void check_inode_bitmaps(e2fsck_t ctx);
9662 static void check_inode_end(e2fsck_t ctx);
9663 static void check_block_end(e2fsck_t ctx);
9665 void e2fsck_pass5(e2fsck_t ctx)
9667 #ifdef RESOURCE_TRACK
9668 struct resource_track rtrack;
9670 struct problem_context pctx;
9673 mtrace_print("Pass 5");
9676 #ifdef RESOURCE_TRACK
9677 init_resource_track(&rtrack);
9680 clear_problem_context(&pctx);
9682 if (!(ctx->options & E2F_OPT_PREEN))
9683 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
9686 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
9689 e2fsck_read_bitmaps(ctx);
9691 check_block_bitmaps(ctx);
9692 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9694 check_inode_bitmaps(ctx);
9695 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9697 check_inode_end(ctx);
9698 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9700 check_block_end(ctx);
9701 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9704 ext2fs_free_inode_bitmap(ctx->inode_used_map);
9705 ctx->inode_used_map = 0;
9706 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
9707 ctx->inode_dir_map = 0;
9708 ext2fs_free_block_bitmap(ctx->block_found_map);
9709 ctx->block_found_map = 0;
9711 #ifdef RESOURCE_TRACK
9712 if (ctx->options & E2F_OPT_TIME2) {
9713 e2fsck_clear_progbar(ctx);
9714 print_resource_track(_("Pass 5"), &rtrack);
9719 #define NO_BLK ((blk_t) -1)
9721 static void print_bitmap_problem(e2fsck_t ctx, int problem,
9722 struct problem_context *pctx)
9725 case PR_5_BLOCK_UNUSED:
9726 if (pctx->blk == pctx->blk2)
9729 problem = PR_5_BLOCK_RANGE_UNUSED;
9731 case PR_5_BLOCK_USED:
9732 if (pctx->blk == pctx->blk2)
9735 problem = PR_5_BLOCK_RANGE_USED;
9737 case PR_5_INODE_UNUSED:
9738 if (pctx->ino == pctx->ino2)
9741 problem = PR_5_INODE_RANGE_UNUSED;
9743 case PR_5_INODE_USED:
9744 if (pctx->ino == pctx->ino2)
9747 problem = PR_5_INODE_RANGE_USED;
9750 fix_problem(ctx, problem, pctx);
9751 pctx->blk = pctx->blk2 = NO_BLK;
9752 pctx->ino = pctx->ino2 = 0;
9755 static void check_block_bitmaps(e2fsck_t ctx)
9757 ext2_filsys fs = ctx->fs;
9761 unsigned int blocks = 0;
9762 unsigned int free_blocks = 0;
9765 struct problem_context pctx;
9766 int problem, save_problem, fixit, had_problem;
9769 clear_problem_context(&pctx);
9770 free_array = (int *) e2fsck_allocate_memory(ctx,
9771 fs->group_desc_count * sizeof(int), "free block count array");
9773 if ((fs->super->s_first_data_block <
9774 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
9775 (fs->super->s_blocks_count-1 >
9776 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
9778 pctx.blk = fs->super->s_first_data_block;
9779 pctx.blk2 = fs->super->s_blocks_count -1;
9780 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
9781 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
9782 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9784 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9788 if ((fs->super->s_first_data_block <
9789 ext2fs_get_block_bitmap_start(fs->block_map)) ||
9790 (fs->super->s_blocks_count-1 >
9791 ext2fs_get_block_bitmap_end(fs->block_map))) {
9793 pctx.blk = fs->super->s_first_data_block;
9794 pctx.blk2 = fs->super->s_blocks_count -1;
9795 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
9796 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
9797 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9799 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9806 pctx.blk = pctx.blk2 = NO_BLK;
9807 for (i = fs->super->s_first_data_block;
9808 i < fs->super->s_blocks_count;
9810 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
9811 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
9813 if (actual == bitmap)
9816 if (!actual && bitmap) {
9818 * Block not used, but marked in use in the bitmap.
9820 problem = PR_5_BLOCK_UNUSED;
9823 * Block used, but not marked in use in the bitmap.
9825 problem = PR_5_BLOCK_USED;
9827 if (pctx.blk == NO_BLK) {
9828 pctx.blk = pctx.blk2 = i;
9829 save_problem = problem;
9831 if ((problem == save_problem) &&
9835 print_bitmap_problem(ctx, save_problem, &pctx);
9836 pctx.blk = pctx.blk2 = i;
9837 save_problem = problem;
9840 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9849 if ((blocks == fs->super->s_blocks_per_group) ||
9850 (i == fs->super->s_blocks_count-1)) {
9851 free_array[group] = group_free;
9856 if ((ctx->progress)(ctx, 5, group,
9857 fs->group_desc_count*2))
9861 if (pctx.blk != NO_BLK)
9862 print_bitmap_problem(ctx, save_problem, &pctx);
9864 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
9867 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9870 ext2fs_free_block_bitmap(fs->block_map);
9871 retval = ext2fs_copy_bitmap(ctx->block_found_map,
9874 clear_problem_context(&pctx);
9875 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
9876 ctx->flags |= E2F_FLAG_ABORT;
9879 ext2fs_set_bitmap_padding(fs->block_map);
9880 ext2fs_mark_bb_dirty(fs);
9882 /* Redo the counts */
9883 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
9884 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9886 } else if (fixit == 0)
9887 ext2fs_unmark_valid(fs);
9889 for (i = 0; i < fs->group_desc_count; i++) {
9890 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
9892 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
9893 pctx.blk2 = free_array[i];
9895 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
9897 fs->group_desc[i].bg_free_blocks_count =
9899 ext2fs_mark_super_dirty(fs);
9901 ext2fs_unmark_valid(fs);
9904 if (free_blocks != fs->super->s_free_blocks_count) {
9906 pctx.blk = fs->super->s_free_blocks_count;
9907 pctx.blk2 = free_blocks;
9909 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
9910 fs->super->s_free_blocks_count = free_blocks;
9911 ext2fs_mark_super_dirty(fs);
9913 ext2fs_unmark_valid(fs);
9915 ext2fs_free_mem(&free_array);
9918 static void check_inode_bitmaps(e2fsck_t ctx)
9920 ext2_filsys fs = ctx->fs;
9922 unsigned int free_inodes = 0;
9926 unsigned int inodes = 0;
9931 struct problem_context pctx;
9932 int problem, save_problem, fixit, had_problem;
9934 clear_problem_context(&pctx);
9935 free_array = (int *) e2fsck_allocate_memory(ctx,
9936 fs->group_desc_count * sizeof(int), "free inode count array");
9938 dir_array = (int *) e2fsck_allocate_memory(ctx,
9939 fs->group_desc_count * sizeof(int), "directory count array");
9941 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
9942 (fs->super->s_inodes_count >
9943 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
9946 pctx.blk2 = fs->super->s_inodes_count;
9947 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
9948 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
9949 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9951 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9954 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
9955 (fs->super->s_inodes_count >
9956 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
9959 pctx.blk2 = fs->super->s_inodes_count;
9960 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
9961 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
9962 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9964 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9971 pctx.ino = pctx.ino2 = 0;
9972 for (i = 1; i <= fs->super->s_inodes_count; i++) {
9973 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
9974 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
9976 if (actual == bitmap)
9979 if (!actual && bitmap) {
9981 * Inode wasn't used, but marked in bitmap
9983 problem = PR_5_INODE_UNUSED;
9984 } else /* if (actual && !bitmap) */ {
9986 * Inode used, but not in bitmap
9988 problem = PR_5_INODE_USED;
9990 if (pctx.ino == 0) {
9991 pctx.ino = pctx.ino2 = i;
9992 save_problem = problem;
9994 if ((problem == save_problem) &&
9998 print_bitmap_problem(ctx, save_problem, &pctx);
9999 pctx.ino = pctx.ino2 = i;
10000 save_problem = problem;
10003 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
10011 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
10015 if ((inodes == fs->super->s_inodes_per_group) ||
10016 (i == fs->super->s_inodes_count)) {
10017 free_array[group] = group_free;
10018 dir_array[group] = dirs_count;
10024 if ((ctx->progress)(ctx, 5,
10025 group + fs->group_desc_count,
10026 fs->group_desc_count*2))
10031 print_bitmap_problem(ctx, save_problem, &pctx);
10034 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
10037 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
10040 ext2fs_free_inode_bitmap(fs->inode_map);
10041 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
10044 clear_problem_context(&pctx);
10045 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
10046 ctx->flags |= E2F_FLAG_ABORT;
10049 ext2fs_set_bitmap_padding(fs->inode_map);
10050 ext2fs_mark_ib_dirty(fs);
10053 inodes = 0; free_inodes = 0; group_free = 0;
10054 dirs_count = 0; group = 0;
10055 memset(free_array, 0, fs->group_desc_count * sizeof(int));
10056 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
10058 } else if (fixit == 0)
10059 ext2fs_unmark_valid(fs);
10061 for (i = 0; i < fs->group_desc_count; i++) {
10062 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
10064 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
10065 pctx.ino2 = free_array[i];
10066 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
10068 fs->group_desc[i].bg_free_inodes_count =
10070 ext2fs_mark_super_dirty(fs);
10072 ext2fs_unmark_valid(fs);
10074 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
10076 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
10077 pctx.ino2 = dir_array[i];
10079 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
10081 fs->group_desc[i].bg_used_dirs_count =
10083 ext2fs_mark_super_dirty(fs);
10085 ext2fs_unmark_valid(fs);
10088 if (free_inodes != fs->super->s_free_inodes_count) {
10090 pctx.ino = fs->super->s_free_inodes_count;
10091 pctx.ino2 = free_inodes;
10093 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
10094 fs->super->s_free_inodes_count = free_inodes;
10095 ext2fs_mark_super_dirty(fs);
10097 ext2fs_unmark_valid(fs);
10099 ext2fs_free_mem(&free_array);
10100 ext2fs_free_mem(&dir_array);
10103 static void check_inode_end(e2fsck_t ctx)
10105 ext2_filsys fs = ctx->fs;
10106 ext2_ino_t end, save_inodes_count, i;
10107 struct problem_context pctx;
10109 clear_problem_context(&pctx);
10111 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
10112 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
10113 &save_inodes_count);
10114 if (pctx.errcode) {
10116 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10117 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10120 if (save_inodes_count == end)
10123 for (i = save_inodes_count + 1; i <= end; i++) {
10124 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
10125 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
10126 for (i = save_inodes_count + 1; i <= end; i++)
10127 ext2fs_mark_inode_bitmap(fs->inode_map,
10129 ext2fs_mark_ib_dirty(fs);
10131 ext2fs_unmark_valid(fs);
10136 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
10137 save_inodes_count, 0);
10138 if (pctx.errcode) {
10140 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10141 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10146 static void check_block_end(e2fsck_t ctx)
10148 ext2_filsys fs = ctx->fs;
10149 blk_t end, save_blocks_count, i;
10150 struct problem_context pctx;
10152 clear_problem_context(&pctx);
10154 end = fs->block_map->start +
10155 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
10156 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
10157 &save_blocks_count);
10158 if (pctx.errcode) {
10160 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10161 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10164 if (save_blocks_count == end)
10167 for (i = save_blocks_count + 1; i <= end; i++) {
10168 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
10169 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
10170 for (i = save_blocks_count + 1; i <= end; i++)
10171 ext2fs_mark_block_bitmap(fs->block_map,
10173 ext2fs_mark_bb_dirty(fs);
10175 ext2fs_unmark_valid(fs);
10180 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
10181 save_blocks_count, 0);
10182 if (pctx.errcode) {
10184 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
10185 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
10193 * problem.c --- report filesystem problems to the user
10195 * Copyright 1996, 1997 by Theodore Ts'o
10198 * This file may be redistributed under the terms of the GNU Public
10203 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
10204 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
10205 #define PR_NO_DEFAULT 0x000004 /* Default to no */
10206 #define PR_MSG_ONLY 0x000008 /* Print message only */
10208 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
10210 #define PR_FATAL 0x001000 /* Fatal error */
10211 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
10213 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
10214 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
10215 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
10216 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
10217 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
10220 #define PROMPT_NONE 0
10221 #define PROMPT_FIX 1
10222 #define PROMPT_CLEAR 2
10223 #define PROMPT_RELOCATE 3
10224 #define PROMPT_ALLOCATE 4
10225 #define PROMPT_EXPAND 5
10226 #define PROMPT_CONNECT 6
10227 #define PROMPT_CREATE 7
10228 #define PROMPT_SALVAGE 8
10229 #define PROMPT_TRUNCATE 9
10230 #define PROMPT_CLEAR_INODE 10
10231 #define PROMPT_ABORT 11
10232 #define PROMPT_SPLIT 12
10233 #define PROMPT_CONTINUE 13
10234 #define PROMPT_CLONE 14
10235 #define PROMPT_DELETE 15
10236 #define PROMPT_SUPPRESS 16
10237 #define PROMPT_UNLINK 17
10238 #define PROMPT_CLEAR_HTREE 18
10239 #define PROMPT_RECREATE 19
10240 #define PROMPT_NULL 20
10242 struct e2fsck_problem {
10243 problem_t e2p_code;
10244 const char * e2p_description;
10247 problem_t second_code;
10250 struct latch_descr {
10252 problem_t question;
10253 problem_t end_message;
10258 * These are the prompts which are used to ask the user if they want
10259 * to fix a problem.
10261 static const char *prompt[] = {
10262 N_("(no prompt)"), /* 0 */
10264 N_("Clear"), /* 2 */
10265 N_("Relocate"), /* 3 */
10266 N_("Allocate"), /* 4 */
10267 N_("Expand"), /* 5 */
10268 N_("Connect to /lost+found"), /* 6 */
10269 N_("Create"), /* 7 */
10270 N_("Salvage"), /* 8 */
10271 N_("Truncate"), /* 9 */
10272 N_("Clear inode"), /* 10 */
10273 N_("Abort"), /* 11 */
10274 N_("Split"), /* 12 */
10275 N_("Continue"), /* 13 */
10276 N_("Clone duplicate/bad blocks"), /* 14 */
10277 N_("Delete file"), /* 15 */
10278 N_("Suppress messages"),/* 16 */
10279 N_("Unlink"), /* 17 */
10280 N_("Clear HTree index"),/* 18 */
10281 N_("Recreate"), /* 19 */
10286 * These messages are printed when we are preen mode and we will be
10287 * automatically fixing the problem.
10289 static const char *preen_msg[] = {
10290 N_("(NONE)"), /* 0 */
10291 N_("FIXED"), /* 1 */
10292 N_("CLEARED"), /* 2 */
10293 N_("RELOCATED"), /* 3 */
10294 N_("ALLOCATED"), /* 4 */
10295 N_("EXPANDED"), /* 5 */
10296 N_("RECONNECTED"), /* 6 */
10297 N_("CREATED"), /* 7 */
10298 N_("SALVAGED"), /* 8 */
10299 N_("TRUNCATED"), /* 9 */
10300 N_("INODE CLEARED"), /* 10 */
10301 N_("ABORTED"), /* 11 */
10302 N_("SPLIT"), /* 12 */
10303 N_("CONTINUING"), /* 13 */
10304 N_("DUPLICATE/BAD BLOCKS CLONED"), /* 14 */
10305 N_("FILE DELETED"), /* 15 */
10306 N_("SUPPRESSED"), /* 16 */
10307 N_("UNLINKED"), /* 17 */
10308 N_("HTREE INDEX CLEARED"),/* 18 */
10309 N_("WILL RECREATE"), /* 19 */
10313 static const struct e2fsck_problem problem_table[] = {
10315 /* Pre-Pass 1 errors */
10317 /* Block bitmap not in group */
10318 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
10319 PROMPT_RELOCATE, PR_LATCH_RELOC },
10321 /* Inode bitmap not in group */
10322 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
10323 PROMPT_RELOCATE, PR_LATCH_RELOC },
10325 /* Inode table not in group */
10326 { PR_0_ITABLE_NOT_GROUP,
10327 N_("@i table for @g %g is not in @g. (@b %b)\n"
10328 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
10329 PROMPT_RELOCATE, PR_LATCH_RELOC },
10331 /* Superblock corrupt */
10333 N_("\nThe @S could not be read or does not describe a correct ext2\n"
10334 "@f. If the @v is valid and it really contains an ext2\n"
10335 "@f (and not swap or ufs or something else), then the @S\n"
10336 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
10337 " e2fsck -b %S <@v>\n\n"),
10338 PROMPT_NONE, PR_FATAL },
10340 /* Filesystem size is wrong */
10341 { PR_0_FS_SIZE_WRONG,
10342 N_("The @f size (according to the @S) is %b @bs\n"
10343 "The physical size of the @v is %c @bs\n"
10344 "Either the @S or the partition table is likely to be corrupt!\n"),
10347 /* Fragments not supported */
10348 { PR_0_NO_FRAGMENTS,
10349 N_("@S @b_size = %b, fragsize = %c.\n"
10350 "This version of e2fsck does not support fragment sizes different\n"
10351 "from the @b size.\n"),
10352 PROMPT_NONE, PR_FATAL },
10354 /* Bad blocks_per_group */
10355 { PR_0_BLOCKS_PER_GROUP,
10356 N_("@S @bs_per_group = %b, should have been %c\n"),
10357 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10359 /* Bad first_data_block */
10360 { PR_0_FIRST_DATA_BLOCK,
10361 N_("@S first_data_@b = %b, should have been %c\n"),
10362 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10364 /* Adding UUID to filesystem */
10366 N_("@f did not have a UUID; generating one.\n\n"),
10369 /* Relocate hint */
10370 { PR_0_RELOCATE_HINT,
10371 N_("Note: if there is several inode or block bitmap blocks\n"
10372 "which require relocation, or one part of the inode table\n"
10373 "which must be moved, you may wish to try running e2fsck\n"
10374 "with the '-b %S' option first. The problem may lie only\n"
10375 "with the primary block group descriptor, and the backup\n"
10376 "block group descriptor may be OK.\n\n"),
10377 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
10379 /* Miscellaneous superblock corruption */
10380 { PR_0_MISC_CORRUPT_SUPER,
10381 N_("Corruption found in @S. (%s = %N).\n"),
10382 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10384 /* Error determing physical device size of filesystem */
10385 { PR_0_GETSIZE_ERROR,
10386 N_("Error determining size of the physical @v: %m\n"),
10387 PROMPT_NONE, PR_FATAL },
10389 /* Inode count in superblock is incorrect */
10390 { PR_0_INODE_COUNT_WRONG,
10391 N_("@i count in @S is %i, should be %j.\n"),
10394 { PR_0_HURD_CLEAR_FILETYPE,
10395 N_("The Hurd does not support the filetype feature.\n"),
10398 /* Journal inode is invalid */
10399 { PR_0_JOURNAL_BAD_INODE,
10400 N_("@S has a bad ext3 @j (@i %i).\n"),
10401 PROMPT_CLEAR, PR_PREEN_OK },
10403 /* The external journal has (unsupported) multiple filesystems */
10404 { PR_0_JOURNAL_UNSUPP_MULTIFS,
10405 N_("External @j has multiple @f users (unsupported).\n"),
10406 PROMPT_NONE, PR_FATAL },
10408 /* Can't find external journal */
10409 { PR_0_CANT_FIND_JOURNAL,
10410 N_("Can't find external @j\n"),
10411 PROMPT_NONE, PR_FATAL },
10413 /* External journal has bad superblock */
10414 { PR_0_EXT_JOURNAL_BAD_SUPER,
10415 N_("External @j has bad @S\n"),
10416 PROMPT_NONE, PR_FATAL },
10418 /* Superblock has a bad journal UUID */
10419 { PR_0_JOURNAL_BAD_UUID,
10420 N_("External @j does not support this @f\n"),
10421 PROMPT_NONE, PR_FATAL },
10423 /* Journal has an unknown superblock type */
10424 { PR_0_JOURNAL_UNSUPP_SUPER,
10425 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
10426 "It is likely that your copy of e2fsck is old and/or doesn't "
10427 "support this @j format.\n"
10428 "It is also possible the @j @S is corrupt.\n"),
10429 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
10431 /* Journal superblock is corrupt */
10432 { PR_0_JOURNAL_BAD_SUPER,
10433 N_("Ext3 @j @S is corrupt.\n"),
10434 PROMPT_FIX, PR_PREEN_OK },
10436 /* Superblock flag should be cleared */
10437 { PR_0_JOURNAL_HAS_JOURNAL,
10438 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
10439 PROMPT_CLEAR, PR_PREEN_OK },
10441 /* Superblock flag is incorrect */
10442 { PR_0_JOURNAL_RECOVER_SET,
10443 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
10444 PROMPT_CLEAR, PR_PREEN_OK },
10446 /* Journal has data, but recovery flag is clear */
10447 { PR_0_JOURNAL_RECOVERY_CLEAR,
10448 N_("ext3 recovery flag clear, but @j has data.\n"),
10451 /* Ask if we should clear the journal */
10452 { PR_0_JOURNAL_RESET_JOURNAL,
10454 PROMPT_NULL, PR_PREEN_NOMSG },
10456 /* Ask if we should run the journal anyway */
10457 { PR_0_JOURNAL_RUN,
10458 N_("Run @j anyway"),
10461 /* Run the journal by default */
10462 { PR_0_JOURNAL_RUN_DEFAULT,
10463 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
10466 /* Clearing orphan inode */
10467 { PR_0_ORPHAN_CLEAR_INODE,
10468 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
10471 /* Illegal block found in orphaned inode */
10472 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
10473 N_("@I @b #%B (%b) found in @o @i %i.\n"),
10476 /* Already cleared block found in orphaned inode */
10477 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
10478 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
10481 /* Illegal orphan inode in superblock */
10482 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
10483 N_("@I @o @i %i in @S.\n"),
10486 /* Illegal inode in orphaned inode list */
10487 { PR_0_ORPHAN_ILLEGAL_INODE,
10488 N_("@I @i %i in @o @i list.\n"),
10491 /* Filesystem revision is 0, but feature flags are set */
10492 { PR_0_FS_REV_LEVEL,
10493 "@f has feature flag(s) set, but is a revision 0 @f. ",
10494 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10496 /* Journal superblock has an unknown read-only feature flag set */
10497 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
10498 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
10501 /* Journal superblock has an unknown incompatible feature flag set */
10502 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
10503 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
10506 /* Journal has unsupported version number */
10507 { PR_0_JOURNAL_UNSUPP_VERSION,
10508 N_("@j version not supported by this e2fsck.\n"),
10511 /* Moving journal to hidden file */
10512 { PR_0_MOVE_JOURNAL,
10513 N_("Moving @j from /%s to hidden inode.\n\n"),
10516 /* Error moving journal to hidden file */
10517 { PR_0_ERR_MOVE_JOURNAL,
10518 N_("Error moving @j: %m\n\n"),
10521 /* Clearing V2 journal superblock */
10522 { PR_0_CLEAR_V2_JOURNAL,
10523 N_("Found invalid V2 @j @S fields (from V1 journal).\n"
10524 "Clearing fields beyond the V1 @j @S...\n\n"),
10527 /* Backup journal inode blocks */
10529 N_("Backing up @j @i @b information.\n\n"),
10532 /* Reserved blocks w/o resize_inode */
10533 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
10534 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
10535 "is %N; @s zero. "),
10538 /* Resize_inode not enabled, but resize inode is non-zero */
10539 { PR_0_CLEAR_RESIZE_INODE,
10540 N_("Resize_@i not enabled, but the resize inode is non-zero. "),
10543 /* Resize inode invalid */
10544 { PR_0_RESIZE_INODE_INVALID,
10545 N_("Resize @i not valid. "),
10546 PROMPT_RECREATE, 0 },
10548 /* Pass 1 errors */
10550 /* Pass 1: Checking inodes, blocks, and sizes */
10551 { PR_1_PASS_HEADER,
10552 N_("Pass 1: Checking @is, @bs, and sizes\n"),
10555 /* Root directory is not an inode */
10556 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
10559 /* Root directory has dtime set */
10561 N_("@r has dtime set (probably due to old mke2fs). "),
10562 PROMPT_FIX, PR_PREEN_OK },
10564 /* Reserved inode has bad mode */
10565 { PR_1_RESERVED_BAD_MODE,
10566 N_("Reserved @i %i %Q has bad mode. "),
10567 PROMPT_CLEAR, PR_PREEN_OK },
10569 /* Deleted inode has zero dtime */
10571 N_("@D @i %i has zero dtime. "),
10572 PROMPT_FIX, PR_PREEN_OK },
10574 /* Inode in use, but dtime set */
10576 N_("@i %i is in use, but has dtime set. "),
10577 PROMPT_FIX, PR_PREEN_OK },
10579 /* Zero-length directory */
10580 { PR_1_ZERO_LENGTH_DIR,
10581 N_("@i %i is a @z @d. "),
10582 PROMPT_CLEAR, PR_PREEN_OK },
10584 /* Block bitmap conflicts with some other fs block */
10585 { PR_1_BB_CONFLICT,
10586 N_("@g %g's @b @B at %b @C.\n"),
10587 PROMPT_RELOCATE, 0 },
10589 /* Inode bitmap conflicts with some other fs block */
10590 { PR_1_IB_CONFLICT,
10591 N_("@g %g's @i @B at %b @C.\n"),
10592 PROMPT_RELOCATE, 0 },
10594 /* Inode table conflicts with some other fs block */
10595 { PR_1_ITABLE_CONFLICT,
10596 N_("@g %g's @i table at %b @C.\n"),
10597 PROMPT_RELOCATE, 0 },
10599 /* Block bitmap is on a bad block */
10600 { PR_1_BB_BAD_BLOCK,
10601 N_("@g %g's @b @B (%b) is bad. "),
10602 PROMPT_RELOCATE, 0 },
10604 /* Inode bitmap is on a bad block */
10605 { PR_1_IB_BAD_BLOCK,
10606 N_("@g %g's @i @B (%b) is bad. "),
10607 PROMPT_RELOCATE, 0 },
10609 /* Inode has incorrect i_size */
10611 N_("@i %i, i_size is %Is, @s %N. "),
10612 PROMPT_FIX, PR_PREEN_OK },
10614 /* Inode has incorrect i_blocks */
10615 { PR_1_BAD_I_BLOCKS,
10616 N_("@i %i, i_@bs is %Ib, @s %N. "),
10617 PROMPT_FIX, PR_PREEN_OK },
10619 /* Illegal blocknumber in inode */
10620 { PR_1_ILLEGAL_BLOCK_NUM,
10621 N_("@I @b #%B (%b) in @i %i. "),
10622 PROMPT_CLEAR, PR_LATCH_BLOCK },
10624 /* Block number overlaps fs metadata */
10625 { PR_1_BLOCK_OVERLAPS_METADATA,
10626 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
10627 PROMPT_CLEAR, PR_LATCH_BLOCK },
10629 /* Inode has illegal blocks (latch question) */
10630 { PR_1_INODE_BLOCK_LATCH,
10631 N_("@i %i has illegal @b(s). "),
10634 /* Too many bad blocks in inode */
10635 { PR_1_TOO_MANY_BAD_BLOCKS,
10636 N_("Too many illegal @bs in @i %i.\n"),
10637 PROMPT_CLEAR_INODE, PR_NO_OK },
10639 /* Illegal block number in bad block inode */
10640 { PR_1_BB_ILLEGAL_BLOCK_NUM,
10641 N_("@I @b #%B (%b) in bad @b @i. "),
10642 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10644 /* Bad block inode has illegal blocks (latch question) */
10645 { PR_1_INODE_BBLOCK_LATCH,
10646 N_("Bad @b @i has illegal @b(s). "),
10649 /* Duplicate or bad blocks in use! */
10650 { PR_1_DUP_BLOCKS_PREENSTOP,
10651 N_("Duplicate or bad @b in use!\n"),
10654 /* Bad block used as bad block indirect block */
10655 { PR_1_BBINODE_BAD_METABLOCK,
10656 N_("Bad @b %b used as bad @b @i indirect @b. "),
10657 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10659 /* Inconsistency can't be fixed prompt */
10660 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
10661 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
10662 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
10664 PROMPT_CONTINUE, PR_PREEN_NOMSG },
10666 /* Bad primary block */
10667 { PR_1_BAD_PRIMARY_BLOCK,
10668 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
10669 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
10671 /* Bad primary block prompt */
10672 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
10673 N_("You can clear the this @b (and hope for the best) from the\n"
10674 "bad @b list and hope that @b is really OK, but there are no\n"
10675 "guarantees.\n\n"),
10676 PROMPT_CLEAR, PR_PREEN_NOMSG },
10678 /* Bad primary superblock */
10679 { PR_1_BAD_PRIMARY_SUPERBLOCK,
10680 N_("The primary @S (%b) is on the bad @b list.\n"),
10681 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10683 /* Bad primary block group descriptors */
10684 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
10685 N_("Block %b in the primary @g descriptors "
10686 "is on the bad @b list\n"),
10687 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10689 /* Bad superblock in group */
10690 { PR_1_BAD_SUPERBLOCK,
10691 N_("Warning: Group %g's @S (%b) is bad.\n"),
10692 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10694 /* Bad block group descriptors in group */
10695 { PR_1_BAD_GROUP_DESCRIPTORS,
10696 N_("Warning: Group %g's copy of the @g descriptors has a bad "
10698 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10700 /* Block claimed for no reason */
10701 { PR_1_PROGERR_CLAIMED_BLOCK,
10702 N_("Programming error? @b #%b claimed for no reason in "
10703 "process_bad_@b.\n"),
10704 PROMPT_NONE, PR_PREEN_OK },
10706 /* Error allocating blocks for relocating metadata */
10707 { PR_1_RELOC_BLOCK_ALLOCATE,
10708 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
10709 PROMPT_NONE, PR_PREEN_OK },
10711 /* Error allocating block buffer during relocation process */
10712 { PR_1_RELOC_MEMORY_ALLOCATE,
10713 N_("@A @b buffer for relocating %s\n"),
10714 PROMPT_NONE, PR_PREEN_OK },
10716 /* Relocating metadata group information from X to Y */
10717 { PR_1_RELOC_FROM_TO,
10718 N_("Relocating @g %g's %s from %b to %c...\n"),
10719 PROMPT_NONE, PR_PREEN_OK },
10721 /* Relocating metatdata group information to X */
10723 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
10724 PROMPT_NONE, PR_PREEN_OK },
10726 /* Block read error during relocation process */
10727 { PR_1_RELOC_READ_ERR,
10728 N_("Warning: could not read @b %b of %s: %m\n"),
10729 PROMPT_NONE, PR_PREEN_OK },
10731 /* Block write error during relocation process */
10732 { PR_1_RELOC_WRITE_ERR,
10733 N_("Warning: could not write @b %b for %s: %m\n"),
10734 PROMPT_NONE, PR_PREEN_OK },
10736 /* Error allocating inode bitmap */
10737 { PR_1_ALLOCATE_IBITMAP_ERROR,
10738 "@A @i @B (%N): %m\n",
10739 PROMPT_NONE, PR_FATAL },
10741 /* Error allocating block bitmap */
10742 { PR_1_ALLOCATE_BBITMAP_ERROR,
10743 "@A @b @B (%N): %m\n",
10744 PROMPT_NONE, PR_FATAL },
10746 /* Error allocating icount structure */
10747 { PR_1_ALLOCATE_ICOUNT,
10748 N_("@A icount link information: %m\n"),
10749 PROMPT_NONE, PR_FATAL },
10751 /* Error allocating dbcount */
10752 { PR_1_ALLOCATE_DBCOUNT,
10753 N_("@A @d @b array: %m\n"),
10754 PROMPT_NONE, PR_FATAL },
10756 /* Error while scanning inodes */
10757 { PR_1_ISCAN_ERROR,
10758 N_("Error while scanning @is (%i): %m\n"),
10759 PROMPT_NONE, PR_FATAL },
10761 /* Error while iterating over blocks */
10762 { PR_1_BLOCK_ITERATE,
10763 N_("Error while iterating over @bs in @i %i: %m\n"),
10764 PROMPT_NONE, PR_FATAL },
10766 /* Error while storing inode count information */
10767 { PR_1_ICOUNT_STORE,
10768 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
10769 PROMPT_NONE, PR_FATAL },
10771 /* Error while storing directory block information */
10773 N_("Error storing @d @b information "
10774 "(@i=%i, @b=%b, num=%N): %m\n"),
10775 PROMPT_NONE, PR_FATAL },
10777 /* Error while reading inode (for clearing) */
10779 N_("Error reading @i %i: %m\n"),
10780 PROMPT_NONE, PR_FATAL },
10782 /* Suppress messages prompt */
10783 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
10785 /* Imagic flag set on an inode when filesystem doesn't support it */
10787 N_("@i %i has imagic flag set. "),
10790 /* Immutable flag set on a device or socket inode */
10791 { PR_1_SET_IMMUTABLE,
10792 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
10793 "or append-only flag set. "),
10794 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
10796 /* Compression flag set on an inode when filesystem doesn't support it */
10798 N_("@i %i has @cion flag set on @f without @cion support. "),
10801 /* Non-zero size for device, fifo or socket inode */
10802 { PR_1_SET_NONZSIZE,
10803 "Special (@v/socket/fifo) @i %i has non-zero size. ",
10804 PROMPT_FIX, PR_PREEN_OK },
10806 /* Filesystem revision is 0, but feature flags are set */
10807 { PR_1_FS_REV_LEVEL,
10808 "@f has feature flag(s) set, but is a revision 0 @f. ",
10809 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10811 /* Journal inode is not in use, but contains data */
10812 { PR_1_JOURNAL_INODE_NOT_CLEAR,
10813 "@j @i is not in use, but contains data. ",
10814 PROMPT_CLEAR, PR_PREEN_OK },
10816 /* Journal has bad mode */
10817 { PR_1_JOURNAL_BAD_MODE,
10818 N_("@j is not regular file. "),
10819 PROMPT_FIX, PR_PREEN_OK },
10821 /* Deal with inodes that were part of orphan linked list */
10823 N_("@i %i was part of the orphaned @i list. "),
10824 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
10826 /* Deal with inodes that were part of corrupted orphan linked
10827 list (latch question) */
10828 { PR_1_ORPHAN_LIST_REFUGEES,
10829 N_("@is that were part of a corrupted orphan linked list found. "),
10832 /* Error allocating refcount structure */
10833 { PR_1_ALLOCATE_REFCOUNT,
10834 "@A refcount structure (%N): %m\n",
10835 PROMPT_NONE, PR_FATAL },
10837 /* Error reading extended attribute block */
10838 { PR_1_READ_EA_BLOCK,
10839 N_("Error reading @a @b %b for @i %i. "),
10842 /* Invalid extended attribute block */
10843 { PR_1_BAD_EA_BLOCK,
10844 N_("@i %i has a bad @a @b %b. "),
10847 /* Error reading Extended Attribute block while fixing refcount */
10848 { PR_1_EXTATTR_READ_ABORT,
10849 N_("Error reading @a @b %b (%m). "),
10852 /* Extended attribute reference count incorrect */
10853 { PR_1_EXTATTR_REFCOUNT,
10854 N_("@a @b %b has reference count %B, should be %N. "),
10857 /* Error writing Extended Attribute block while fixing refcount */
10858 { PR_1_EXTATTR_WRITE,
10859 N_("Error writing @a @b %b (%m). "),
10862 /* Multiple EA blocks not supported */
10863 { PR_1_EA_MULTI_BLOCK,
10864 N_("@a @b %b has h_blocks > 1. "),
10867 /* Error allocating EA region allocation structure */
10868 { PR_1_EA_ALLOC_REGION,
10869 N_("Error allocating @a @b %b. "),
10872 /* Error EA allocation collision */
10873 { PR_1_EA_ALLOC_COLLISION,
10874 N_("@a @b %b is corrupt (allocation collision). "),
10877 /* Bad extended attribute name */
10878 { PR_1_EA_BAD_NAME,
10879 N_("@a @b %b is corrupt (invalid name). "),
10882 /* Bad extended attribute value */
10883 { PR_1_EA_BAD_VALUE,
10884 N_("@a @b %b is corrupt (invalid value). "),
10887 /* Inode too big (latch question) */
10888 { PR_1_INODE_TOOBIG,
10889 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
10891 /* Directory too big */
10893 N_("@b #%B (%b) causes @d to be too big. "),
10894 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10896 /* Regular file too big */
10898 N_("@b #%B (%b) causes file to be too big. "),
10899 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10901 /* Symlink too big */
10902 { PR_1_TOOBIG_SYMLINK,
10903 N_("@b #%B (%b) causes symlink to be too big. "),
10904 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10906 /* INDEX_FL flag set on a non-HTREE filesystem */
10908 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
10909 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10911 /* INDEX_FL flag set on a non-directory */
10912 { PR_1_HTREE_NODIR,
10913 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
10914 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10916 /* Invalid root node in HTREE directory */
10917 { PR_1_HTREE_BADROOT,
10918 N_("@h %i has an invalid root node.\n"),
10919 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10921 /* Unsupported hash version in HTREE directory */
10922 { PR_1_HTREE_HASHV,
10923 N_("@h %i has an unsupported hash version (%N)\n"),
10924 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10926 /* Incompatible flag in HTREE root node */
10927 { PR_1_HTREE_INCOMPAT,
10928 N_("@h %i uses an incompatible htree root node flag.\n"),
10929 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10931 /* HTREE too deep */
10932 { PR_1_HTREE_DEPTH,
10933 N_("@h %i has a tree depth (%N) which is too big\n"),
10934 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10936 /* Bad block has indirect block that conflicts with filesystem block */
10937 { PR_1_BB_FS_BLOCK,
10938 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
10940 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10942 /* Resize inode failed */
10943 { PR_1_RESIZE_INODE_CREATE,
10944 N_("Resize @i (re)creation failed: %m."),
10947 /* invalid inode->i_extra_isize */
10948 { PR_1_EXTRA_ISIZE,
10949 N_("@i %i has a extra size (%IS) which is invalid\n"),
10950 PROMPT_FIX, PR_PREEN_OK },
10952 /* invalid ea entry->e_name_len */
10953 { PR_1_ATTR_NAME_LEN,
10954 N_("@a in @i %i has a namelen (%N) which is invalid\n"),
10955 PROMPT_CLEAR, PR_PREEN_OK },
10957 /* invalid ea entry->e_value_size */
10958 { PR_1_ATTR_VALUE_SIZE,
10959 N_("@a in @i %i has a value size (%N) which is invalid\n"),
10960 PROMPT_CLEAR, PR_PREEN_OK },
10962 /* invalid ea entry->e_value_offs */
10963 { PR_1_ATTR_VALUE_OFFSET,
10964 N_("@a in @i %i has a value offset (%N) which is invalid\n"),
10965 PROMPT_CLEAR, PR_PREEN_OK },
10967 /* invalid ea entry->e_value_block */
10968 { PR_1_ATTR_VALUE_BLOCK,
10969 N_("@a in @i %i has a value block (%N) which is invalid (must be 0)\n"),
10970 PROMPT_CLEAR, PR_PREEN_OK },
10972 /* invalid ea entry->e_hash */
10974 N_("@a in @i %i has a hash (%N) which is invalid (must be 0)\n"),
10975 PROMPT_CLEAR, PR_PREEN_OK },
10977 /* Pass 1b errors */
10979 /* Pass 1B: Rescan for duplicate/bad blocks */
10980 { PR_1B_PASS_HEADER,
10981 N_("Duplicate @bs found... invoking duplicate @b passes.\n"
10982 "Pass 1B: Rescan for duplicate/bad @bs\n"),
10985 /* Duplicate/bad block(s) header */
10986 { PR_1B_DUP_BLOCK_HEADER,
10987 N_("Duplicate/bad @b(s) in @i %i:"),
10990 /* Duplicate/bad block(s) in inode */
10993 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
10995 /* Duplicate/bad block(s) end */
10996 { PR_1B_DUP_BLOCK_END,
10998 PROMPT_NONE, PR_PREEN_NOHDR },
11000 /* Error while scanning inodes */
11001 { PR_1B_ISCAN_ERROR,
11002 N_("Error while scanning inodes (%i): %m\n"),
11003 PROMPT_NONE, PR_FATAL },
11005 /* Error allocating inode bitmap */
11006 { PR_1B_ALLOCATE_IBITMAP_ERROR,
11007 N_("@A @i @B (inode_dup_map): %m\n"),
11008 PROMPT_NONE, PR_FATAL },
11010 /* Error while iterating over blocks */
11011 { PR_1B_BLOCK_ITERATE,
11012 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
11015 /* Error adjusting EA refcount */
11016 { PR_1B_ADJ_EA_REFCOUNT,
11017 N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
11021 /* Pass 1C: Scan directories for inodes with dup blocks. */
11022 { PR_1C_PASS_HEADER,
11023 N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
11027 /* Pass 1D: Reconciling duplicate blocks */
11028 { PR_1D_PASS_HEADER,
11029 N_("Pass 1D: Reconciling duplicate @bs\n"),
11032 /* File has duplicate blocks */
11034 N_("File %Q (@i #%i, mod time %IM) \n"
11035 " has %B duplicate @b(s), shared with %N file(s):\n"),
11038 /* List of files sharing duplicate blocks */
11039 { PR_1D_DUP_FILE_LIST,
11040 N_("\t%Q (@i #%i, mod time %IM)\n"),
11043 /* File sharing blocks with filesystem metadata */
11044 { PR_1D_SHARE_METADATA,
11045 N_("\t<@f metadata>\n"),
11048 /* Report of how many duplicate/bad inodes */
11049 { PR_1D_NUM_DUP_INODES,
11050 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
11053 /* Duplicated blocks already reassigned or cloned. */
11054 { PR_1D_DUP_BLOCKS_DEALT,
11055 N_("Duplicated @bs already reassigned or cloned.\n\n"),
11058 /* Clone duplicate/bad blocks? */
11059 { PR_1D_CLONE_QUESTION,
11060 "", PROMPT_CLONE, PR_NO_OK },
11063 { PR_1D_DELETE_QUESTION,
11064 "", PROMPT_DELETE, 0 },
11066 /* Couldn't clone file (error) */
11067 { PR_1D_CLONE_ERROR,
11068 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
11070 /* Pass 2 errors */
11072 /* Pass 2: Checking directory structure */
11073 { PR_2_PASS_HEADER,
11074 N_("Pass 2: Checking @d structure\n"),
11077 /* Bad inode number for '.' */
11078 { PR_2_BAD_INODE_DOT,
11079 N_("Bad @i number for '.' in @d @i %i.\n"),
11082 /* Directory entry has bad inode number */
11084 N_("@E has bad @i #: %Di.\n"),
11087 /* Directory entry has deleted or unused inode */
11088 { PR_2_UNUSED_INODE,
11089 N_("@E has @D/unused @i %Di. "),
11090 PROMPT_CLEAR, PR_PREEN_OK },
11092 /* Directry entry is link to '.' */
11094 N_("@E @L to '.' "),
11097 /* Directory entry points to inode now located in a bad block */
11099 N_("@E points to @i (%Di) located in a bad @b.\n"),
11102 /* Directory entry contains a link to a directory */
11104 N_("@E @L to @d %P (%Di).\n"),
11107 /* Directory entry contains a link to the root directry */
11109 N_("@E @L to the @r.\n"),
11112 /* Directory entry has illegal characters in its name */
11114 N_("@E has illegal characters in its name.\n"),
11117 /* Missing '.' in directory inode */
11118 { PR_2_MISSING_DOT,
11119 N_("Missing '.' in @d @i %i.\n"),
11122 /* Missing '..' in directory inode */
11123 { PR_2_MISSING_DOT_DOT,
11124 N_("Missing '..' in @d @i %i.\n"),
11127 /* First entry in directory inode doesn't contain '.' */
11128 { PR_2_1ST_NOT_DOT,
11129 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
11132 /* Second entry in directory inode doesn't contain '..' */
11133 { PR_2_2ND_NOT_DOT_DOT,
11134 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
11137 /* i_faddr should be zero */
11139 N_("i_faddr @F %IF, @s zero.\n"),
11142 /* i_file_acl should be zero */
11143 { PR_2_FILE_ACL_ZERO,
11144 N_("i_file_acl @F %If, @s zero.\n"),
11147 /* i_dir_acl should be zero */
11148 { PR_2_DIR_ACL_ZERO,
11149 N_("i_dir_acl @F %Id, @s zero.\n"),
11152 /* i_frag should be zero */
11154 N_("i_frag @F %N, @s zero.\n"),
11157 /* i_fsize should be zero */
11159 N_("i_fsize @F %N, @s zero.\n"),
11162 /* inode has bad mode */
11164 N_("@i %i (%Q) has a bad mode (%Im).\n"),
11167 /* directory corrupted */
11168 { PR_2_DIR_CORRUPTED,
11169 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
11170 PROMPT_SALVAGE, 0 },
11172 /* filename too long */
11173 { PR_2_FILENAME_LONG,
11174 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
11175 PROMPT_TRUNCATE, 0 },
11177 /* Directory inode has a missing block (hole) */
11178 { PR_2_DIRECTORY_HOLE,
11179 N_("@d @i %i has an unallocated @b #%B. "),
11180 PROMPT_ALLOCATE, 0 },
11182 /* '.' is not NULL terminated */
11183 { PR_2_DOT_NULL_TERM,
11184 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
11187 /* '..' is not NULL terminated */
11188 { PR_2_DOT_DOT_NULL_TERM,
11189 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
11192 /* Illegal character device inode */
11193 { PR_2_BAD_CHAR_DEV,
11194 N_("@i %i (%Q) is an @I character @v.\n"),
11197 /* Illegal block device inode */
11198 { PR_2_BAD_BLOCK_DEV,
11199 N_("@i %i (%Q) is an @I @b @v.\n"),
11202 /* Duplicate '.' entry */
11204 N_("@E is duplicate '.' @e.\n"),
11207 /* Duplicate '..' entry */
11208 { PR_2_DUP_DOT_DOT,
11209 N_("@E is duplicate '..' @e.\n"),
11212 /* Internal error: couldn't find dir_info */
11214 N_("Internal error: couldn't find dir_info for %i.\n"),
11215 PROMPT_NONE, PR_FATAL },
11217 /* Final rec_len is wrong */
11218 { PR_2_FINAL_RECLEN,
11219 N_("@E has rec_len of %Dr, should be %N.\n"),
11222 /* Error allocating icount structure */
11223 { PR_2_ALLOCATE_ICOUNT,
11224 N_("@A icount structure: %m\n"),
11225 PROMPT_NONE, PR_FATAL },
11227 /* Error iterating over directory blocks */
11228 { PR_2_DBLIST_ITERATE,
11229 N_("Error iterating over @d @bs: %m\n"),
11230 PROMPT_NONE, PR_FATAL },
11232 /* Error reading directory block */
11233 { PR_2_READ_DIRBLOCK,
11234 N_("Error reading @d @b %b (@i %i): %m\n"),
11235 PROMPT_CONTINUE, 0 },
11237 /* Error writing directory block */
11238 { PR_2_WRITE_DIRBLOCK,
11239 N_("Error writing @d @b %b (@i %i): %m\n"),
11240 PROMPT_CONTINUE, 0 },
11242 /* Error allocating new directory block */
11243 { PR_2_ALLOC_DIRBOCK,
11244 N_("@A new @d @b for @i %i (%s): %m\n"),
11247 /* Error deallocating inode */
11248 { PR_2_DEALLOC_INODE,
11249 N_("Error deallocating @i %i: %m\n"),
11250 PROMPT_NONE, PR_FATAL },
11252 /* Directory entry for '.' is big. Split? */
11254 N_("@d @e for '.' is big. "),
11255 PROMPT_SPLIT, PR_NO_OK },
11257 /* Illegal FIFO inode */
11259 N_("@i %i (%Q) is an @I FIFO.\n"),
11262 /* Illegal socket inode */
11264 N_("@i %i (%Q) is an @I socket.\n"),
11267 /* Directory filetype not set */
11268 { PR_2_SET_FILETYPE,
11269 N_("Setting filetype for @E to %N.\n"),
11270 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
11272 /* Directory filetype incorrect */
11273 { PR_2_BAD_FILETYPE,
11274 N_("@E has an incorrect filetype (was %Dt, should be %N).\n"),
11277 /* Directory filetype set on filesystem */
11278 { PR_2_CLEAR_FILETYPE,
11279 N_("@E has filetype set.\n"),
11280 PROMPT_CLEAR, PR_PREEN_OK },
11282 /* Directory filename is null */
11284 N_("@E has a zero-length name.\n"),
11287 /* Invalid symlink */
11288 { PR_2_INVALID_SYMLINK,
11289 N_("Symlink %Q (@i #%i) is invalid.\n"),
11292 /* i_file_acl (extended attribute block) is bad */
11293 { PR_2_FILE_ACL_BAD,
11294 N_("@a @b @F invalid (%If).\n"),
11297 /* Filesystem contains large files, but has no such flag in sb */
11298 { PR_2_FEATURE_LARGE_FILES,
11299 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
11302 /* Node in HTREE directory not referenced */
11303 { PR_2_HTREE_NOTREF,
11304 N_("@p @h %d: node (%B) not referenced\n"),
11307 /* Node in HTREE directory referenced twice */
11308 { PR_2_HTREE_DUPREF,
11309 N_("@p @h %d: node (%B) referenced twice\n"),
11312 /* Node in HTREE directory has bad min hash */
11313 { PR_2_HTREE_MIN_HASH,
11314 N_("@p @h %d: node (%B) has bad min hash\n"),
11317 /* Node in HTREE directory has bad max hash */
11318 { PR_2_HTREE_MAX_HASH,
11319 N_("@p @h %d: node (%B) has bad max hash\n"),
11322 /* Clear invalid HTREE directory */
11323 { PR_2_HTREE_CLEAR,
11324 N_("Invalid @h %d (%q). "), PROMPT_CLEAR, 0 },
11326 /* Bad block in htree interior node */
11327 { PR_2_HTREE_BADBLK,
11328 N_("@p @h %d (%q): bad @b number %b.\n"),
11329 PROMPT_CLEAR_HTREE, 0 },
11331 /* Error adjusting EA refcount */
11332 { PR_2_ADJ_EA_REFCOUNT,
11333 N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
11334 PROMPT_NONE, PR_FATAL },
11336 /* Invalid HTREE root node */
11337 { PR_2_HTREE_BAD_ROOT,
11338 N_("@p @h %d: root node is invalid\n"),
11339 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11341 /* Invalid HTREE limit */
11342 { PR_2_HTREE_BAD_LIMIT,
11343 N_("@p @h %d: node (%B) has bad limit (%N)\n"),
11344 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11346 /* Invalid HTREE count */
11347 { PR_2_HTREE_BAD_COUNT,
11348 N_("@p @h %d: node (%B) has bad count (%N)\n"),
11349 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11351 /* HTREE interior node has out-of-order hashes in table */
11352 { PR_2_HTREE_HASH_ORDER,
11353 N_("@p @h %d: node (%B) has an unordered hash table\n"),
11354 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11356 /* Node in HTREE directory has bad depth */
11357 { PR_2_HTREE_BAD_DEPTH,
11358 N_("@p @h %d: node (%B) has bad depth\n"),
11361 /* Duplicate directory entry found */
11362 { PR_2_DUPLICATE_DIRENT,
11363 N_("Duplicate @E found. "),
11366 /* Non-unique filename found */
11367 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
11368 N_("@E has a non-unique filename.\nRename to %s"),
11371 /* Duplicate directory entry found */
11372 { PR_2_REPORT_DUP_DIRENT,
11373 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
11376 /* Pass 3 errors */
11378 /* Pass 3: Checking directory connectivity */
11379 { PR_3_PASS_HEADER,
11380 N_("Pass 3: Checking @d connectivity\n"),
11383 /* Root inode not allocated */
11384 { PR_3_NO_ROOT_INODE,
11385 N_("@r not allocated. "),
11386 PROMPT_ALLOCATE, 0 },
11388 /* No room in lost+found */
11389 { PR_3_EXPAND_LF_DIR,
11390 N_("No room in @l @d. "),
11391 PROMPT_EXPAND, 0 },
11393 /* Unconnected directory inode */
11394 { PR_3_UNCONNECTED_DIR,
11395 N_("Unconnected @d @i %i (%p)\n"),
11396 PROMPT_CONNECT, 0 },
11398 /* /lost+found not found */
11400 N_("/@l not found. "),
11401 PROMPT_CREATE, PR_PREEN_OK },
11403 /* .. entry is incorrect */
11404 { PR_3_BAD_DOT_DOT,
11405 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
11408 /* Bad or non-existent /lost+found. Cannot reconnect */
11410 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
11413 /* Could not expand /lost+found */
11414 { PR_3_CANT_EXPAND_LPF,
11415 N_("Could not expand /@l: %m\n"),
11418 /* Could not reconnect inode */
11419 { PR_3_CANT_RECONNECT,
11420 N_("Could not reconnect %i: %m\n"),
11423 /* Error while trying to find /lost+found */
11424 { PR_3_ERR_FIND_LPF,
11425 N_("Error while trying to find /@l: %m\n"),
11428 /* Error in ext2fs_new_block while creating /lost+found */
11429 { PR_3_ERR_LPF_NEW_BLOCK,
11430 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
11433 /* Error in ext2fs_new_inode while creating /lost+found */
11434 { PR_3_ERR_LPF_NEW_INODE,
11435 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
11438 /* Error in ext2fs_new_dir_block while creating /lost+found */
11439 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
11440 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
11443 /* Error while writing directory block for /lost+found */
11444 { PR_3_ERR_LPF_WRITE_BLOCK,
11445 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
11448 /* Error while adjusting inode count */
11449 { PR_3_ADJUST_INODE,
11450 N_("Error while adjusting @i count on @i %i\n"),
11453 /* Couldn't fix parent directory -- error */
11454 { PR_3_FIX_PARENT_ERR,
11455 N_("Couldn't fix parent of @i %i: %m\n\n"),
11458 /* Couldn't fix parent directory -- couldn't find it */
11459 { PR_3_FIX_PARENT_NOFIND,
11460 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
11463 /* Error allocating inode bitmap */
11464 { PR_3_ALLOCATE_IBITMAP_ERROR,
11465 N_("@A @i @B (%N): %m\n"),
11466 PROMPT_NONE, PR_FATAL },
11468 /* Error creating root directory */
11469 { PR_3_CREATE_ROOT_ERROR,
11470 N_("Error creating root @d (%s): %m\n"),
11471 PROMPT_NONE, PR_FATAL },
11473 /* Error creating lost and found directory */
11474 { PR_3_CREATE_LPF_ERROR,
11475 N_("Error creating /@l @d (%s): %m\n"),
11476 PROMPT_NONE, PR_FATAL },
11478 /* Root inode is not directory; aborting */
11479 { PR_3_ROOT_NOT_DIR_ABORT,
11480 N_("@r is not a @d; aborting.\n"),
11481 PROMPT_NONE, PR_FATAL },
11483 /* Cannot proceed without a root inode. */
11484 { PR_3_NO_ROOT_INODE_ABORT,
11485 N_("Cannot proceed without a @r.\n"),
11486 PROMPT_NONE, PR_FATAL },
11488 /* Internal error: couldn't find dir_info */
11490 N_("Internal error: couldn't find dir_info for %i.\n"),
11491 PROMPT_NONE, PR_FATAL },
11493 /* Lost+found not a directory */
11495 N_("/@l is not a @d (ino=%i)\n"),
11496 PROMPT_UNLINK, 0 },
11498 /* Pass 3A Directory Optimization */
11500 /* Pass 3A: Optimizing directories */
11501 { PR_3A_PASS_HEADER,
11502 N_("Pass 3A: Optimizing directories\n"),
11503 PROMPT_NONE, PR_PREEN_NOMSG },
11505 /* Error iterating over directories */
11506 { PR_3A_OPTIMIZE_ITER,
11507 N_("Failed to create dirs_to_hash iterator: %m"),
11510 /* Error rehash directory */
11511 { PR_3A_OPTIMIZE_DIR_ERR,
11512 N_("Failed to optimize directory %q (%d): %m"),
11515 /* Rehashing dir header */
11516 { PR_3A_OPTIMIZE_DIR_HEADER,
11517 N_("Optimizing directories: "),
11518 PROMPT_NONE, PR_MSG_ONLY },
11520 /* Rehashing directory %d */
11521 { PR_3A_OPTIMIZE_DIR,
11523 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
11525 /* Rehashing dir end */
11526 { PR_3A_OPTIMIZE_DIR_END,
11528 PROMPT_NONE, PR_PREEN_NOHDR },
11530 /* Pass 4 errors */
11532 /* Pass 4: Checking reference counts */
11533 { PR_4_PASS_HEADER,
11534 N_("Pass 4: Checking reference counts\n"),
11537 /* Unattached zero-length inode */
11538 { PR_4_ZERO_LEN_INODE,
11540 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
11542 /* Unattached inode */
11543 { PR_4_UNATTACHED_INODE,
11545 PROMPT_CONNECT, 0 },
11547 /* Inode ref count wrong */
11548 { PR_4_BAD_REF_COUNT,
11549 N_("@i %i ref count is %Il, @s %N. "),
11550 PROMPT_FIX, PR_PREEN_OK },
11552 { PR_4_INCONSISTENT_COUNT,
11553 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
11554 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
11555 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
11556 "They should be the same!\n"),
11559 /* Pass 5 errors */
11561 /* Pass 5: Checking group summary information */
11562 { PR_5_PASS_HEADER,
11563 N_("Pass 5: Checking @g summary information\n"),
11566 /* Padding at end of inode bitmap is not set. */
11567 { PR_5_INODE_BMAP_PADDING,
11568 N_("Padding at end of @i @B is not set. "),
11569 PROMPT_FIX, PR_PREEN_OK },
11571 /* Padding at end of block bitmap is not set. */
11572 { PR_5_BLOCK_BMAP_PADDING,
11573 N_("Padding at end of @b @B is not set. "),
11574 PROMPT_FIX, PR_PREEN_OK },
11576 /* Block bitmap differences header */
11577 { PR_5_BLOCK_BITMAP_HEADER,
11578 N_("@b @B differences: "),
11579 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
11581 /* Block not used, but marked in bitmap */
11582 { PR_5_BLOCK_UNUSED,
11584 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11586 /* Block used, but not marked used in bitmap */
11589 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11591 /* Block bitmap differences end */
11592 { PR_5_BLOCK_BITMAP_END,
11594 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11596 /* Inode bitmap differences header */
11597 { PR_5_INODE_BITMAP_HEADER,
11598 N_("@i @B differences: "),
11599 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
11601 /* Inode not used, but marked in bitmap */
11602 { PR_5_INODE_UNUSED,
11604 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11606 /* Inode used, but not marked used in bitmap */
11609 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11611 /* Inode bitmap differences end */
11612 { PR_5_INODE_BITMAP_END,
11614 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11616 /* Free inodes count for group wrong */
11617 { PR_5_FREE_INODE_COUNT_GROUP,
11618 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
11619 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11621 /* Directories count for group wrong */
11622 { PR_5_FREE_DIR_COUNT_GROUP,
11623 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
11624 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11626 /* Free inodes count wrong */
11627 { PR_5_FREE_INODE_COUNT,
11628 N_("Free @is count wrong (%i, counted=%j).\n"),
11629 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11631 /* Free blocks count for group wrong */
11632 { PR_5_FREE_BLOCK_COUNT_GROUP,
11633 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
11634 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11636 /* Free blocks count wrong */
11637 { PR_5_FREE_BLOCK_COUNT,
11638 N_("Free @bs count wrong (%b, counted=%c).\n"),
11639 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11641 /* Programming error: bitmap endpoints don't match */
11642 { PR_5_BMAP_ENDPOINTS,
11643 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
11644 "match calculated @B endpoints (%i, %j)\n"),
11645 PROMPT_NONE, PR_FATAL },
11647 /* Internal error: fudging end of bitmap */
11648 { PR_5_FUDGE_BITMAP_ERROR,
11649 N_("Internal error: fudging end of bitmap (%N)\n"),
11650 PROMPT_NONE, PR_FATAL },
11652 /* Error copying in replacement inode bitmap */
11653 { PR_5_COPY_IBITMAP_ERROR,
11654 "Error copying in replacement @i @B: %m\n",
11655 PROMPT_NONE, PR_FATAL },
11657 /* Error copying in replacement block bitmap */
11658 { PR_5_COPY_BBITMAP_ERROR,
11659 "Error copying in replacement @b @B: %m\n",
11660 PROMPT_NONE, PR_FATAL },
11662 /* Block range not used, but marked in bitmap */
11663 { PR_5_BLOCK_RANGE_UNUSED,
11665 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11667 /* Block range used, but not marked used in bitmap */
11668 { PR_5_BLOCK_RANGE_USED,
11670 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11672 /* Inode range not used, but marked in bitmap */
11673 { PR_5_INODE_RANGE_UNUSED,
11675 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11677 /* Inode range used, but not marked used in bitmap */
11678 { PR_5_INODE_RANGE_USED,
11680 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11686 * This is the latch flags register. It allows several problems to be
11687 * "latched" together. This means that the user has to answer but one
11688 * question for the set of problems, and all of the associated
11689 * problems will be either fixed or not fixed.
11691 static struct latch_descr pr_latch_info[] = {
11692 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
11693 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
11694 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
11695 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
11696 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
11697 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
11698 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
11699 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
11700 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
11704 static const struct e2fsck_problem *find_problem(problem_t code)
11708 for (i=0; problem_table[i].e2p_code; i++) {
11709 if (problem_table[i].e2p_code == code)
11710 return &problem_table[i];
11715 static struct latch_descr *find_latch(int code)
11719 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
11720 if (pr_latch_info[i].latch_code == code)
11721 return &pr_latch_info[i];
11726 int end_problem_latch(e2fsck_t ctx, int mask)
11728 struct latch_descr *ldesc;
11729 struct problem_context pctx;
11732 ldesc = find_latch(mask);
11733 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
11734 clear_problem_context(&pctx);
11735 answer = fix_problem(ctx, ldesc->end_message, &pctx);
11737 ldesc->flags &= ~(PRL_VARIABLE);
11741 int set_latch_flags(int mask, int setflags, int clearflags)
11743 struct latch_descr *ldesc;
11745 ldesc = find_latch(mask);
11748 ldesc->flags |= setflags;
11749 ldesc->flags &= ~clearflags;
11753 void clear_problem_context(struct problem_context *ctx)
11755 memset(ctx, 0, sizeof(struct problem_context));
11756 ctx->blkcount = -1;
11760 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
11762 ext2_filsys fs = ctx->fs;
11763 const struct e2fsck_problem *ptr;
11764 struct latch_descr *ldesc = 0;
11765 const char *message;
11766 int def_yn, answer, ans;
11767 int print_answer = 0;
11770 ptr = find_problem(code);
11772 printf(_("Unhandled error code (0x%x)!\n"), code);
11776 if ((ptr->flags & PR_NO_DEFAULT) ||
11777 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
11778 (ctx->options & E2F_OPT_NO))
11782 * Do special latch processing. This is where we ask the
11783 * latch question, if it exists
11785 if (ptr->flags & PR_LATCH_MASK) {
11786 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
11787 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
11788 ans = fix_problem(ctx, ldesc->question, pctx);
11790 ldesc->flags |= PRL_YES;
11792 ldesc->flags |= PRL_NO;
11793 ldesc->flags |= PRL_LATCHED;
11795 if (ldesc->flags & PRL_SUPPRESS)
11798 if ((ptr->flags & PR_PREEN_NOMSG) &&
11799 (ctx->options & E2F_OPT_PREEN))
11801 if ((ptr->flags & PR_NO_NOMSG) &&
11802 (ctx->options & E2F_OPT_NO))
11805 message = ptr->e2p_description;
11806 if ((ctx->options & E2F_OPT_PREEN) &&
11807 !(ptr->flags & PR_PREEN_NOHDR)) {
11808 printf("%s: ", ctx->device_name ?
11809 ctx->device_name : ctx->filesystem_name);
11812 print_e2fsck_message(ctx, _(message), pctx, 1);
11814 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
11817 if (ptr->flags & PR_FATAL)
11818 fatal_error(ctx, 0);
11820 if (ptr->prompt == PROMPT_NONE) {
11821 if (ptr->flags & PR_NOCOLLATE)
11826 if (ctx->options & E2F_OPT_PREEN) {
11828 if (!(ptr->flags & PR_PREEN_NOMSG))
11830 } else if ((ptr->flags & PR_LATCH_MASK) &&
11831 (ldesc->flags & (PRL_YES | PRL_NO))) {
11834 if (ldesc->flags & PRL_YES)
11839 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
11840 if (!answer && !(ptr->flags & PR_NO_OK))
11841 ext2fs_unmark_valid(fs);
11844 printf("%s.\n", answer ?
11845 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
11849 if ((ptr->prompt == PROMPT_ABORT) && answer)
11850 fatal_error(ctx, 0);
11852 if (ptr->flags & PR_AFTER_CODE)
11853 answer = fix_problem(ctx, ptr->second_code, pctx);
11858 * linux/fs/recovery.c
11860 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
11862 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
11864 * This file is part of the Linux kernel and is made available under
11865 * the terms of the GNU General Public License, version 2, or at your
11866 * option, any later version, incorporated herein by reference.
11868 * Journal recovery routines for the generic filesystem journaling code;
11869 * part of the ext2fs journaling system.
11873 * Maintain information about the progress of the recovery job, so that
11874 * the different passes can carry information between them.
11876 struct recovery_info
11878 tid_t start_transaction;
11879 tid_t end_transaction;
11883 int nr_revoke_hits;
11886 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
11887 static int do_one_pass(journal_t *journal,
11888 struct recovery_info *info, enum passtype pass);
11889 static int scan_revoke_records(journal_t *, struct buffer_head *,
11890 tid_t, struct recovery_info *);
11894 /* Release readahead buffers after use */
11895 void journal_brelse_array(struct buffer_head *b[], int n)
11903 * When reading from the journal, we are going through the block device
11904 * layer directly and so there is no readahead being done for us. We
11905 * need to implement any readahead ourselves if we want it to happen at
11906 * all. Recovery is basically one long sequential read, so make sure we
11907 * do the IO in reasonably large chunks.
11909 * This is not so critical that we need to be enormously clever about
11910 * the readahead size, though. 128K is a purely arbitrary, good-enough
11915 static int do_readahead(journal_t *journal, unsigned int start)
11918 unsigned int max, nbufs, next;
11919 unsigned long blocknr;
11920 struct buffer_head *bh;
11922 struct buffer_head * bufs[MAXBUF];
11924 /* Do up to 128K of readahead */
11925 max = start + (128 * 1024 / journal->j_blocksize);
11926 if (max > journal->j_maxlen)
11927 max = journal->j_maxlen;
11929 /* Do the readahead itself. We'll submit MAXBUF buffer_heads at
11930 * a time to the block device IO layer. */
11934 for (next = start; next < max; next++) {
11935 err = journal_bmap(journal, next, &blocknr);
11938 printk (KERN_ERR "JBD: bad block at offset %u\n",
11943 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
11949 if (!buffer_uptodate(bh) && !buffer_locked(bh)) {
11950 bufs[nbufs++] = bh;
11951 if (nbufs == MAXBUF) {
11952 ll_rw_block(READ, nbufs, bufs);
11953 journal_brelse_array(bufs, nbufs);
11961 ll_rw_block(READ, nbufs, bufs);
11966 journal_brelse_array(bufs, nbufs);
11970 #endif /* __KERNEL__ */
11974 * Read a block from the journal
11977 static int jread(struct buffer_head **bhp, journal_t *journal,
11978 unsigned int offset)
11981 unsigned long blocknr;
11982 struct buffer_head *bh;
11986 J_ASSERT (offset < journal->j_maxlen);
11988 err = journal_bmap(journal, offset, &blocknr);
11991 printk (KERN_ERR "JBD: bad block at offset %u\n",
11996 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
12000 if (!buffer_uptodate(bh)) {
12001 /* If this is a brand new buffer, start readahead.
12002 Otherwise, we assume we are already reading it. */
12003 if (!buffer_req(bh))
12004 do_readahead(journal, offset);
12005 wait_on_buffer(bh);
12008 if (!buffer_uptodate(bh)) {
12009 printk (KERN_ERR "JBD: Failed to read block at offset %u\n",
12021 * Count the number of in-use tags in a journal descriptor block.
12024 static int count_tags(struct buffer_head *bh, int size)
12027 journal_block_tag_t * tag;
12030 tagp = &bh->b_data[sizeof(journal_header_t)];
12032 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
12033 tag = (journal_block_tag_t *) tagp;
12036 tagp += sizeof(journal_block_tag_t);
12037 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
12040 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
12048 /* Make sure we wrap around the log correctly! */
12049 #define wrap(journal, var) \
12051 if (var >= (journal)->j_last) \
12052 var -= ((journal)->j_last - (journal)->j_first); \
12056 * int journal_recover(journal_t *journal) - recovers a on-disk journal
12057 * @journal: the journal to recover
12059 * The primary function for recovering the log contents when mounting a
12060 * journaled device.
12062 * Recovery is done in three passes. In the first pass, we look for the
12063 * end of the log. In the second, we assemble the list of revoke
12064 * blocks. In the third and final pass, we replay any un-revoked blocks
12067 int journal_recover(journal_t *journal)
12070 journal_superblock_t * sb;
12072 struct recovery_info info;
12074 memset(&info, 0, sizeof(info));
12075 sb = journal->j_superblock;
12078 * The journal superblock's s_start field (the current log head)
12079 * is always zero if, and only if, the journal was cleanly
12083 if (!sb->s_start) {
12084 jbd_debug(1, "No recovery required, last transaction %d\n",
12085 ntohl(sb->s_sequence));
12086 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
12090 err = do_one_pass(journal, &info, PASS_SCAN);
12092 err = do_one_pass(journal, &info, PASS_REVOKE);
12094 err = do_one_pass(journal, &info, PASS_REPLAY);
12096 jbd_debug(0, "JBD: recovery, exit status %d, "
12097 "recovered transactions %u to %u\n",
12098 err, info.start_transaction, info.end_transaction);
12099 jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
12100 info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
12102 /* Restart the log at the next transaction ID, thus invalidating
12103 * any existing commit records in the log. */
12104 journal->j_transaction_sequence = ++info.end_transaction;
12106 journal_clear_revoke(journal);
12107 sync_blockdev(journal->j_fs_dev);
12111 static int do_one_pass(journal_t *journal,
12112 struct recovery_info *info, enum passtype pass)
12114 unsigned int first_commit_ID, next_commit_ID;
12115 unsigned long next_log_block;
12116 int err, success = 0;
12117 journal_superblock_t * sb;
12118 journal_header_t * tmp;
12119 struct buffer_head * bh;
12120 unsigned int sequence;
12123 /* Precompute the maximum metadata descriptors in a descriptor block */
12124 int MAX_BLOCKS_PER_DESC;
12125 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
12126 / sizeof(journal_block_tag_t));
12129 * First thing is to establish what we expect to find in the log
12130 * (in terms of transaction IDs), and where (in terms of log
12131 * block offsets): query the superblock.
12134 sb = journal->j_superblock;
12135 next_commit_ID = ntohl(sb->s_sequence);
12136 next_log_block = ntohl(sb->s_start);
12138 first_commit_ID = next_commit_ID;
12139 if (pass == PASS_SCAN)
12140 info->start_transaction = first_commit_ID;
12142 jbd_debug(1, "Starting recovery pass %d\n", pass);
12145 * Now we walk through the log, transaction by transaction,
12146 * making sure that each transaction has a commit block in the
12147 * expected place. Each complete transaction gets replayed back
12148 * into the main filesystem.
12154 journal_block_tag_t * tag;
12155 struct buffer_head * obh;
12156 struct buffer_head * nbh;
12158 /* If we already know where to stop the log traversal,
12159 * check right now that we haven't gone past the end of
12162 if (pass != PASS_SCAN)
12163 if (tid_geq(next_commit_ID, info->end_transaction))
12166 jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
12167 next_commit_ID, next_log_block, journal->j_last);
12169 /* Skip over each chunk of the transaction looking
12170 * either the next descriptor block or the final commit
12173 jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
12174 err = jread(&bh, journal, next_log_block);
12179 wrap(journal, next_log_block);
12181 /* What kind of buffer is it?
12183 * If it is a descriptor block, check that it has the
12184 * expected sequence number. Otherwise, we're all done
12187 tmp = (journal_header_t *)bh->b_data;
12189 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
12194 blocktype = ntohl(tmp->h_blocktype);
12195 sequence = ntohl(tmp->h_sequence);
12196 jbd_debug(3, "Found magic %d, sequence %d\n",
12197 blocktype, sequence);
12199 if (sequence != next_commit_ID) {
12204 /* OK, we have a valid descriptor block which matches
12205 * all of the sequence number checks. What are we going
12206 * to do with it? That depends on the pass... */
12208 switch(blocktype) {
12209 case JFS_DESCRIPTOR_BLOCK:
12210 /* If it is a valid descriptor block, replay it
12211 * in pass REPLAY; otherwise, just skip over the
12212 * blocks it describes. */
12213 if (pass != PASS_REPLAY) {
12215 count_tags(bh, journal->j_blocksize);
12216 wrap(journal, next_log_block);
12221 /* A descriptor block: we can now write all of
12222 * the data blocks. Yay, useful work is finally
12223 * getting done here! */
12225 tagp = &bh->b_data[sizeof(journal_header_t)];
12226 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
12227 <= journal->j_blocksize) {
12228 unsigned long io_block;
12230 tag = (journal_block_tag_t *) tagp;
12231 flags = ntohl(tag->t_flags);
12233 io_block = next_log_block++;
12234 wrap(journal, next_log_block);
12235 err = jread(&obh, journal, io_block);
12237 /* Recover what we can, but
12238 * report failure at the end. */
12241 "JBD: IO error %d recovering "
12242 "block %ld in log\n",
12245 unsigned long blocknr;
12247 J_ASSERT(obh != NULL);
12248 blocknr = ntohl(tag->t_blocknr);
12250 /* If the block has been
12251 * revoked, then we're all done
12253 if (journal_test_revoke
12257 ++info->nr_revoke_hits;
12261 /* Find a buffer for the new
12262 * data being restored */
12263 nbh = __getblk(journal->j_fs_dev,
12265 journal->j_blocksize);
12268 "JBD: Out of memory "
12269 "during recovery.\n");
12277 memcpy(nbh->b_data, obh->b_data,
12278 journal->j_blocksize);
12279 if (flags & JFS_FLAG_ESCAPE) {
12280 *((unsigned int *)bh->b_data) =
12281 htonl(JFS_MAGIC_NUMBER);
12284 BUFFER_TRACE(nbh, "marking dirty");
12285 set_buffer_uptodate(nbh);
12286 mark_buffer_dirty(nbh);
12287 BUFFER_TRACE(nbh, "marking uptodate");
12288 ++info->nr_replays;
12289 /* ll_rw_block(WRITE, 1, &nbh); */
12290 unlock_buffer(nbh);
12296 tagp += sizeof(journal_block_tag_t);
12297 if (!(flags & JFS_FLAG_SAME_UUID))
12300 if (flags & JFS_FLAG_LAST_TAG)
12307 case JFS_COMMIT_BLOCK:
12308 /* Found an expected commit block: not much to
12309 * do other than move on to the next sequence
12315 case JFS_REVOKE_BLOCK:
12316 /* If we aren't in the REVOKE pass, then we can
12317 * just skip over this block. */
12318 if (pass != PASS_REVOKE) {
12323 err = scan_revoke_records(journal, bh,
12324 next_commit_ID, info);
12331 jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
12339 * We broke out of the log scan loop: either we came to the
12340 * known end of the log or we found an unexpected block in the
12341 * log. If the latter happened, then we know that the "current"
12342 * transaction marks the end of the valid log.
12345 if (pass == PASS_SCAN)
12346 info->end_transaction = next_commit_ID;
12348 /* It's really bad news if different passes end up at
12349 * different places (but possible due to IO errors). */
12350 if (info->end_transaction != next_commit_ID) {
12351 printk (KERN_ERR "JBD: recovery pass %d ended at "
12352 "transaction %u, expected %u\n",
12353 pass, next_commit_ID, info->end_transaction);
12366 /* Scan a revoke record, marking all blocks mentioned as revoked. */
12368 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
12369 tid_t sequence, struct recovery_info *info)
12371 journal_revoke_header_t *header;
12374 header = (journal_revoke_header_t *) bh->b_data;
12375 offset = sizeof(journal_revoke_header_t);
12376 max = ntohl(header->r_count);
12378 while (offset < max) {
12379 unsigned long blocknr;
12382 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
12384 err = journal_set_revoke(journal, blocknr, sequence);
12387 ++info->nr_revokes;
12392 * region.c --- code which manages allocations within a region.
12394 * Copyright (C) 2001 Theodore Ts'o.
12397 * This file may be redistributed under the terms of the GNU Public
12403 region_addr_t start;
12405 struct region_el *next;
12408 struct region_struct {
12411 struct region_el *allocated;
12414 region_t region_create(region_addr_t min, region_addr_t max)
12418 region = malloc(sizeof(struct region_struct));
12421 memset(region, 0, sizeof(struct region_struct));
12427 void region_free(region_t region)
12429 struct region_el *r, *next;
12431 for (r = region->allocated; r; r = next) {
12435 memset(region, 0, sizeof(struct region_struct));
12439 int region_allocate(region_t region, region_addr_t start, int n)
12441 struct region_el *r, *new_region, *prev, *next;
12445 if ((start < region->min) || (end > region->max))
12451 * Search through the linked list. If we find that it
12452 * conflicts witih something that's already allocated, return
12453 * 1; if we can find an existing region which we can grow, do
12454 * so. Otherwise, stop when we find the appropriate place
12455 * insert a new region element into the linked list.
12457 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
12458 if (((start >= r->start) && (start < r->end)) ||
12459 ((end > r->start) && (end <= r->end)) ||
12460 ((start <= r->start) && (end >= r->end)))
12462 if (end == r->start) {
12466 if (start == r->end) {
12467 if ((next = r->next)) {
12468 if (end > next->start)
12470 if (end == next->start) {
12471 r->end = next->end;
12472 r->next = next->next;
12480 if (start < r->start)
12484 * Insert a new region element structure into the linked list
12486 new_region = malloc(sizeof(struct region_el));
12489 new_region->start = start;
12490 new_region->end = start + n;
12491 new_region->next = r;
12493 prev->next = new_region;
12495 region->allocated = new_region;
12500 * rehash.c --- rebuild hash tree directories
12502 * Copyright (C) 2002 Theodore Ts'o
12505 * This file may be redistributed under the terms of the GNU Public
12509 * This algorithm is designed for simplicity of implementation and to
12510 * pack the directory as much as possible. It however requires twice
12511 * as much memory as the size of the directory. The maximum size
12512 * directory supported using a 4k blocksize is roughly a gigabyte, and
12513 * so there may very well be problems with machines that don't have
12514 * virtual memory, and obscenely large directories.
12516 * An alternate algorithm which is much more disk intensive could be
12517 * written, and probably will need to be written in the future. The
12518 * design goals of such an algorithm are: (a) use (roughly) constant
12519 * amounts of memory, no matter how large the directory, (b) the
12520 * directory must be safe at all times, even if e2fsck is interrupted
12521 * in the middle, (c) we must use minimal amounts of extra disk
12522 * blocks. This pretty much requires an incremental approach, where
12523 * we are reading from one part of the directory, and inserting into
12524 * the front half. So the algorithm will have to keep track of a
12525 * moving block boundary between the new tree and the old tree, and
12526 * files will need to be moved from the old directory and inserted
12527 * into the new tree. If the new directory requires space which isn't
12528 * yet available, blocks from the beginning part of the old directory
12529 * may need to be moved to the end of the directory to make room for
12532 * --------------------------------------------------------
12533 * | new tree | | old tree |
12534 * --------------------------------------------------------
12536 * tail new head old
12538 * This is going to be a pain in the tuckus to implement, and will
12539 * require a lot more disk accesses. So I'm going to skip it for now;
12540 * it's only really going to be an issue for really, really big
12541 * filesystems (when we reach the level of tens of millions of files
12542 * in a single directory). It will probably be easier to simply
12543 * require that e2fsck use VM first.
12546 struct fill_dir_struct {
12548 struct ext2_inode *inode;
12551 struct hash_entry *harray;
12552 int max_array, num_array;
12558 struct hash_entry {
12559 ext2_dirhash_t hash;
12560 ext2_dirhash_t minor_hash;
12561 struct ext2_dir_entry *dir;
12568 ext2_dirhash_t *hashes;
12571 static int fill_dir_block(ext2_filsys fs,
12573 e2_blkcnt_t blockcnt,
12574 blk_t ref_block EXT2FS_ATTR((unused)),
12575 int ref_offset EXT2FS_ATTR((unused)),
12578 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
12579 struct hash_entry *new_array, *ent;
12580 struct ext2_dir_entry *dirent;
12582 unsigned int offset, dir_offset;
12587 offset = blockcnt * fs->blocksize;
12588 if (offset + fs->blocksize > fd->inode->i_size) {
12589 fd->err = EXT2_ET_DIR_CORRUPTED;
12590 return BLOCK_ABORT;
12592 dir = (fd->buf+offset);
12593 if (HOLE_BLKADDR(*block_nr)) {
12594 memset(dir, 0, fs->blocksize);
12595 dirent = (struct ext2_dir_entry *) dir;
12596 dirent->rec_len = fs->blocksize;
12598 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
12600 return BLOCK_ABORT;
12602 /* While the directory block is "hot", index it. */
12604 while (dir_offset < fs->blocksize) {
12605 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
12606 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
12607 (dirent->rec_len < 8) ||
12608 ((dirent->rec_len % 4) != 0) ||
12609 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
12610 fd->err = EXT2_ET_DIR_CORRUPTED;
12611 return BLOCK_ABORT;
12613 dir_offset += dirent->rec_len;
12614 if (dirent->inode == 0)
12616 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
12617 (dirent->name[0] == '.'))
12619 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
12620 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
12621 fd->parent = dirent->inode;
12624 if (fd->num_array >= fd->max_array) {
12625 new_array = realloc(fd->harray,
12626 sizeof(struct hash_entry) * (fd->max_array+500));
12629 return BLOCK_ABORT;
12631 fd->harray = new_array;
12632 fd->max_array += 500;
12634 ent = fd->harray + fd->num_array++;
12636 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
12638 ent->hash = ent->minor_hash = 0;
12640 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
12642 dirent->name_len & 0xFF,
12643 fs->super->s_hash_seed,
12644 &ent->hash, &ent->minor_hash);
12646 return BLOCK_ABORT;
12653 /* Used for sorting the hash entry */
12654 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
12656 const struct hash_entry *he_a = (const struct hash_entry *) a;
12657 const struct hash_entry *he_b = (const struct hash_entry *) b;
12661 min_len = he_a->dir->name_len;
12662 if (min_len > he_b->dir->name_len)
12663 min_len = he_b->dir->name_len;
12665 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
12667 if (he_a->dir->name_len > he_b->dir->name_len)
12669 else if (he_a->dir->name_len < he_b->dir->name_len)
12672 ret = he_b->dir->inode - he_a->dir->inode;
12677 /* Used for sorting the hash entry */
12678 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
12680 const struct hash_entry *he_a = (const struct hash_entry *) a;
12681 const struct hash_entry *he_b = (const struct hash_entry *) b;
12684 if (he_a->hash > he_b->hash)
12686 else if (he_a->hash < he_b->hash)
12689 if (he_a->minor_hash > he_b->minor_hash)
12691 else if (he_a->minor_hash < he_b->minor_hash)
12694 ret = name_cmp(a, b);
12699 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
12705 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
12708 outdir->buf = new_mem;
12709 new_mem = realloc(outdir->hashes,
12710 blocks * sizeof(ext2_dirhash_t));
12713 outdir->hashes = new_mem;
12715 outdir->buf = malloc(blocks * fs->blocksize);
12716 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
12719 outdir->max = blocks;
12723 static void free_out_dir(struct out_dir *outdir)
12727 if (outdir->hashes)
12728 free(outdir->hashes);
12733 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
12738 if (outdir->num >= outdir->max) {
12739 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
12743 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
12744 memset(*ret, 0, fs->blocksize);
12749 * This function is used to make a unique filename. We do this by
12750 * appending ~0, and then incrementing the number. However, we cannot
12751 * expand the length of the filename beyond the padding available in
12752 * the directory entry.
12754 static void mutate_name(char *str, __u16 *len)
12757 __u16 l = *len & 0xFF, h = *len & 0xff00;
12760 * First check to see if it looks the name has been mutated
12763 for (i = l-1; i > 0; i--) {
12764 if (!isdigit(str[i]))
12767 if ((i == l-1) || (str[i] != '~')) {
12768 if (((l-1) & 3) < 2)
12777 for (i = l-1; i >= 0; i--) {
12778 if (isdigit(str[i])) {
12790 else if (str[0] == 'Z') {
12795 } else if (i > 0) {
12808 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
12810 struct fill_dir_struct *fd)
12812 struct problem_context pctx;
12813 struct hash_entry *ent, *prev;
12816 char new_name[256];
12819 clear_problem_context(&pctx);
12822 for (i=1; i < fd->num_array; i++) {
12823 ent = fd->harray + i;
12825 if (!ent->dir->inode ||
12826 ((ent->dir->name_len & 0xFF) !=
12827 (prev->dir->name_len & 0xFF)) ||
12828 (strncmp(ent->dir->name, prev->dir->name,
12829 ent->dir->name_len & 0xFF)))
12831 pctx.dirent = ent->dir;
12832 if ((ent->dir->inode == prev->dir->inode) &&
12833 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
12834 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
12835 ent->dir->inode = 0;
12839 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
12840 new_len = ent->dir->name_len;
12841 mutate_name(new_name, &new_len);
12842 for (j=0; j < fd->num_array; j++) {
12844 ((ent->dir->name_len & 0xFF) !=
12845 (fd->harray[j].dir->name_len & 0xFF)) ||
12846 (strncmp(new_name, fd->harray[j].dir->name,
12849 mutate_name(new_name, &new_len);
12853 new_name[new_len & 0xFF] = 0;
12854 pctx.str = new_name;
12855 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
12856 memcpy(ent->dir->name, new_name, new_len & 0xFF);
12857 ent->dir->name_len = new_len;
12858 ext2fs_dirhash(fs->super->s_def_hash_version,
12860 ent->dir->name_len & 0xFF,
12861 fs->super->s_hash_seed,
12862 &ent->hash, &ent->minor_hash);
12870 static errcode_t copy_dir_entries(ext2_filsys fs,
12871 struct fill_dir_struct *fd,
12872 struct out_dir *outdir)
12876 struct hash_entry *ent;
12877 struct ext2_dir_entry *dirent;
12878 int i, rec_len, left;
12879 ext2_dirhash_t prev_hash;
12883 retval = alloc_size_dir(fs, outdir,
12884 (fd->dir_size / fs->blocksize) + 2);
12887 outdir->num = fd->compress ? 0 : 1;
12889 outdir->hashes[0] = 0;
12891 if ((retval = get_next_block(fs, outdir, &block_start)))
12893 dirent = (struct ext2_dir_entry *) block_start;
12894 left = fs->blocksize;
12895 for (i=0; i < fd->num_array; i++) {
12896 ent = fd->harray + i;
12897 if (ent->dir->inode == 0)
12899 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
12900 if (rec_len > left) {
12902 dirent->rec_len += left;
12903 if ((retval = get_next_block(fs, outdir,
12908 left = fs->blocksize - offset;
12909 dirent = (struct ext2_dir_entry *) (block_start + offset);
12911 if (ent->hash == prev_hash)
12912 outdir->hashes[outdir->num-1] = ent->hash | 1;
12914 outdir->hashes[outdir->num-1] = ent->hash;
12916 dirent->inode = ent->dir->inode;
12917 dirent->name_len = ent->dir->name_len;
12918 dirent->rec_len = rec_len;
12919 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
12923 dirent->rec_len += left;
12927 prev_hash = ent->hash;
12930 dirent->rec_len += left;
12936 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
12937 ext2_ino_t ino, ext2_ino_t parent)
12939 struct ext2_dir_entry *dir;
12940 struct ext2_dx_root_info *root;
12941 struct ext2_dx_countlimit *limits;
12944 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
12945 filetype = EXT2_FT_DIR << 8;
12947 memset(buf, 0, fs->blocksize);
12948 dir = (struct ext2_dir_entry *) buf;
12950 dir->name[0] = '.';
12951 dir->name_len = 1 | filetype;
12953 dir = (struct ext2_dir_entry *) (buf + 12);
12954 dir->inode = parent;
12955 dir->name[0] = '.';
12956 dir->name[1] = '.';
12957 dir->name_len = 2 | filetype;
12958 dir->rec_len = fs->blocksize - 12;
12960 root = (struct ext2_dx_root_info *) (buf+24);
12961 root->reserved_zero = 0;
12962 root->hash_version = fs->super->s_def_hash_version;
12963 root->info_length = 8;
12964 root->indirect_levels = 0;
12965 root->unused_flags = 0;
12967 limits = (struct ext2_dx_countlimit *) (buf+32);
12968 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
12975 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
12977 struct ext2_dir_entry *dir;
12978 struct ext2_dx_countlimit *limits;
12980 memset(buf, 0, fs->blocksize);
12981 dir = (struct ext2_dir_entry *) buf;
12983 dir->rec_len = fs->blocksize;
12985 limits = (struct ext2_dx_countlimit *) (buf+8);
12986 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
12989 return (struct ext2_dx_entry *) limits;
12993 * This function takes the leaf nodes which have been written in
12994 * outdir, and populates the root node and any necessary interior nodes.
12996 static errcode_t calculate_tree(ext2_filsys fs,
12997 struct out_dir *outdir,
13001 struct ext2_dx_root_info *root_info;
13002 struct ext2_dx_entry *root, *dx_ent = 0;
13003 struct ext2_dx_countlimit *root_limit, *limit;
13005 char * block_start;
13006 int i, c1, c2, nblks;
13007 int limit_offset, root_offset;
13009 root_info = set_root_node(fs, outdir->buf, ino, parent);
13010 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
13011 root_info->info_length;
13012 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
13013 c1 = root_limit->limit;
13014 nblks = outdir->num;
13016 /* Write out the pointer blocks */
13017 if (nblks-1 <= c1) {
13018 /* Just write out the root block, and we're done */
13019 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
13020 for (i=1; i < nblks; i++) {
13021 root->block = ext2fs_cpu_to_le32(i);
13024 ext2fs_cpu_to_le32(outdir->hashes[i]);
13031 root_info->indirect_levels = 1;
13032 for (i=1; i < nblks; i++) {
13037 limit->limit = limit->count =
13038 ext2fs_cpu_to_le16(limit->limit);
13039 root = (struct ext2_dx_entry *)
13040 (outdir->buf + root_offset);
13041 root->block = ext2fs_cpu_to_le32(outdir->num);
13044 ext2fs_cpu_to_le32(outdir->hashes[i]);
13045 if ((retval = get_next_block(fs, outdir,
13048 dx_ent = set_int_node(fs, block_start);
13049 limit = (struct ext2_dx_countlimit *) dx_ent;
13051 root_offset += sizeof(struct ext2_dx_entry);
13054 dx_ent->block = ext2fs_cpu_to_le32(i);
13055 if (c2 != limit->limit)
13057 ext2fs_cpu_to_le32(outdir->hashes[i]);
13061 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
13062 limit->limit = ext2fs_cpu_to_le16(limit->limit);
13064 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
13065 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
13066 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
13071 struct write_dir_struct {
13072 struct out_dir *outdir;
13079 * Helper function which writes out a directory block.
13081 static int write_dir_block(ext2_filsys fs,
13083 e2_blkcnt_t blockcnt,
13084 blk_t ref_block EXT2FS_ATTR((unused)),
13085 int ref_offset EXT2FS_ATTR((unused)),
13088 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
13092 if (*block_nr == 0)
13094 if (blockcnt >= wd->outdir->num) {
13095 e2fsck_read_bitmaps(wd->ctx);
13097 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
13098 ext2fs_block_alloc_stats(fs, blk, -1);
13101 return BLOCK_CHANGED;
13106 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
13107 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
13109 return BLOCK_ABORT;
13113 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
13114 struct out_dir *outdir,
13115 ext2_ino_t ino, int compress)
13117 struct write_dir_struct wd;
13119 struct ext2_inode inode;
13121 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
13125 wd.outdir = outdir;
13130 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
13131 write_dir_block, &wd);
13137 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
13139 inode.i_flags &= ~EXT2_INDEX_FL;
13141 inode.i_flags |= EXT2_INDEX_FL;
13142 inode.i_size = outdir->num * fs->blocksize;
13143 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
13144 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
13149 errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
13151 ext2_filsys fs = ctx->fs;
13153 struct ext2_inode inode;
13155 struct fill_dir_struct fd;
13156 struct out_dir outdir;
13158 outdir.max = outdir.num = 0;
13161 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
13165 dir_buf = malloc(inode.i_size);
13169 fd.max_array = inode.i_size / 32;
13171 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
13181 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
13182 (inode.i_size / fs->blocksize) < 2)
13186 /* Read in the entire directory into memory */
13187 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
13188 fill_dir_block, &fd);
13195 printf("%d entries (%d bytes) found in inode %d\n",
13196 fd.num_array, fd.dir_size, ino);
13199 /* Sort the list */
13202 qsort(fd.harray+2, fd.num_array-2,
13203 sizeof(struct hash_entry), name_cmp);
13205 qsort(fd.harray, fd.num_array,
13206 sizeof(struct hash_entry), hash_cmp);
13209 * Look for duplicates
13211 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
13214 if (ctx->options & E2F_OPT_NO) {
13220 * Copy the directory entries. In a htree directory these
13221 * will become the leaf nodes.
13223 retval = copy_dir_entries(fs, &fd, &outdir);
13227 free(dir_buf); dir_buf = 0;
13229 if (!fd.compress) {
13230 /* Calculate the interior nodes */
13231 retval = calculate_tree(fs, &outdir, ino, fd.parent);
13236 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
13246 free_out_dir(&outdir);
13250 void e2fsck_rehash_directories(e2fsck_t ctx)
13252 struct problem_context pctx;
13253 #ifdef RESOURCE_TRACK
13254 struct resource_track rtrack;
13256 struct dir_info *dir;
13257 ext2_u32_iterate iter;
13260 int i, cur, max, all_dirs, dir_index, first = 1;
13262 #ifdef RESOURCE_TRACK
13263 init_resource_track(&rtrack);
13266 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
13268 if (!ctx->dirs_to_hash && !all_dirs)
13271 e2fsck_get_lost_and_found(ctx, 0);
13273 clear_problem_context(&pctx);
13275 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
13279 max = e2fsck_get_num_dirinfo(ctx);
13281 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
13284 pctx.errcode = retval;
13285 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
13288 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
13292 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
13296 if (!ext2fs_u32_list_iterate(iter, &ino))
13299 if (ino == ctx->lost_and_found)
13303 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
13307 fix_problem(ctx, PR_3A_OPTIMIZE_DIR, &pctx);
13309 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
13310 if (pctx.errcode) {
13311 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
13312 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
13314 if (ctx->progress && !ctx->progress_fd)
13315 e2fsck_simple_progress(ctx, "Rebuilding directory",
13316 100.0 * (float) (++cur) / (float) max, ino);
13318 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
13320 ext2fs_u32_list_iterate_end(iter);
13322 if (ctx->dirs_to_hash)
13323 ext2fs_u32_list_free(ctx->dirs_to_hash);
13324 ctx->dirs_to_hash = 0;
13326 #ifdef RESOURCE_TRACK
13327 if (ctx->options & E2F_OPT_TIME2) {
13328 e2fsck_clear_progbar(ctx);
13329 print_resource_track("Pass 3A", &rtrack);
13334 * linux/fs/revoke.c
13336 * Written by Stephen C. Tweedie <sct@redhat.com>, 2000
13338 * Copyright 2000 Red Hat corp --- All Rights Reserved
13340 * This file is part of the Linux kernel and is made available under
13341 * the terms of the GNU General Public License, version 2, or at your
13342 * option, any later version, incorporated herein by reference.
13344 * Journal revoke routines for the generic filesystem journaling code;
13345 * part of the ext2fs journaling system.
13347 * Revoke is the mechanism used to prevent old log records for deleted
13348 * metadata from being replayed on top of newer data using the same
13349 * blocks. The revoke mechanism is used in two separate places:
13351 * + Commit: during commit we write the entire list of the current
13352 * transaction's revoked blocks to the journal
13354 * + Recovery: during recovery we record the transaction ID of all
13355 * revoked blocks. If there are multiple revoke records in the log
13356 * for a single block, only the last one counts, and if there is a log
13357 * entry for a block beyond the last revoke, then that log entry still
13360 * We can get interactions between revokes and new log data within a
13361 * single transaction:
13363 * Block is revoked and then journaled:
13364 * The desired end result is the journaling of the new block, so we
13365 * cancel the revoke before the transaction commits.
13367 * Block is journaled and then revoked:
13368 * The revoke must take precedence over the write of the block, so we
13369 * need either to cancel the journal entry or to write the revoke
13370 * later in the log than the log block. In this case, we choose the
13371 * latter: journaling a block cancels any revoke record for that block
13372 * in the current transaction, so any revoke for that block in the
13373 * transaction must have happened after the block was journaled and so
13374 * the revoke must take precedence.
13376 * Block is revoked and then written as data:
13377 * The data write is allowed to succeed, but the revoke is _not_
13378 * cancelled. We still need to prevent old log records from
13379 * overwriting the new data. We don't even need to clear the revoke
13382 * Revoke information on buffers is a tri-state value:
13384 * RevokeValid clear: no cached revoke status, need to look it up
13385 * RevokeValid set, Revoked clear:
13386 * buffer has not been revoked, and cancel_revoke
13388 * RevokeValid set, Revoked set:
13389 * buffer has been revoked.
13392 static kmem_cache_t *revoke_record_cache;
13393 static kmem_cache_t *revoke_table_cache;
13395 /* Each revoke record represents one single revoked block. During
13396 journal replay, this involves recording the transaction ID of the
13397 last transaction to revoke this block. */
13399 struct jbd_revoke_record_s
13401 struct list_head hash;
13402 tid_t sequence; /* Used for recovery only */
13403 unsigned long blocknr;
13407 /* The revoke table is just a simple hash table of revoke records. */
13408 struct jbd_revoke_table_s
13410 /* It is conceivable that we might want a larger hash table
13411 * for recovery. Must be a power of two. */
13414 struct list_head *hash_table;
13419 static void write_one_revoke_record(journal_t *, transaction_t *,
13420 struct journal_head **, int *,
13421 struct jbd_revoke_record_s *);
13422 static void flush_descriptor(journal_t *, struct journal_head *, int);
13425 /* Utility functions to maintain the revoke table */
13427 /* Borrowed from buffer.c: this is a tried and tested block hash function */
13428 static inline int hash(journal_t *journal, unsigned long block)
13430 struct jbd_revoke_table_s *table = journal->j_revoke;
13431 int hash_shift = table->hash_shift;
13433 return ((block << (hash_shift - 6)) ^
13435 (block << (hash_shift - 12))) & (table->hash_size - 1);
13438 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
13441 struct list_head *hash_list;
13442 struct jbd_revoke_record_s *record;
13447 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
13451 record->sequence = seq;
13452 record->blocknr = blocknr;
13453 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13454 list_add(&record->hash, hash_list);
13459 if (!journal_oom_retry)
13461 jbd_debug(1, "ENOMEM in " __FUNCTION__ ", retrying.\n");
13462 current->policy |= SCHED_YIELD;
13470 /* Find a revoke record in the journal's hash table. */
13472 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
13473 unsigned long blocknr)
13475 struct list_head *hash_list;
13476 struct jbd_revoke_record_s *record;
13478 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13480 record = (struct jbd_revoke_record_s *) hash_list->next;
13481 while (&(record->hash) != hash_list) {
13482 if (record->blocknr == blocknr)
13484 record = (struct jbd_revoke_record_s *) record->hash.next;
13489 int journal_init_revoke_caches(void)
13491 revoke_record_cache = kmem_cache_create("revoke_record",
13492 sizeof(struct jbd_revoke_record_s),
13493 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
13494 if (revoke_record_cache == 0)
13497 revoke_table_cache = kmem_cache_create("revoke_table",
13498 sizeof(struct jbd_revoke_table_s),
13500 if (revoke_table_cache == 0) {
13501 kmem_cache_destroy(revoke_record_cache);
13502 revoke_record_cache = NULL;
13508 void journal_destroy_revoke_caches(void)
13510 kmem_cache_destroy(revoke_record_cache);
13511 revoke_record_cache = 0;
13512 kmem_cache_destroy(revoke_table_cache);
13513 revoke_table_cache = 0;
13516 /* Initialise the revoke table for a given journal to a given size. */
13518 int journal_init_revoke(journal_t *journal, int hash_size)
13522 J_ASSERT (journal->j_revoke == NULL);
13524 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
13525 if (!journal->j_revoke)
13528 /* Check that the hash_size is a power of two */
13529 J_ASSERT ((hash_size & (hash_size-1)) == 0);
13531 journal->j_revoke->hash_size = hash_size;
13535 while((tmp >>= 1UL) != 0UL)
13537 journal->j_revoke->hash_shift = shift;
13539 journal->j_revoke->hash_table =
13540 kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
13541 if (!journal->j_revoke->hash_table) {
13542 kmem_cache_free(revoke_table_cache, journal->j_revoke);
13543 journal->j_revoke = NULL;
13547 for (tmp = 0; tmp < hash_size; tmp++)
13548 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
13553 /* Destoy a journal's revoke table. The table must already be empty! */
13555 void journal_destroy_revoke(journal_t *journal)
13557 struct jbd_revoke_table_s *table;
13558 struct list_head *hash_list;
13561 table = journal->j_revoke;
13565 for (i=0; i<table->hash_size; i++) {
13566 hash_list = &table->hash_table[i];
13567 J_ASSERT (list_empty(hash_list));
13570 kfree(table->hash_table);
13571 kmem_cache_free(revoke_table_cache, table);
13572 journal->j_revoke = NULL;
13579 * journal_revoke: revoke a given buffer_head from the journal. This
13580 * prevents the block from being replayed during recovery if we take a
13581 * crash after this current transaction commits. Any subsequent
13582 * metadata writes of the buffer in this transaction cancel the
13585 * Note that this call may block --- it is up to the caller to make
13586 * sure that there are no further calls to journal_write_metadata
13587 * before the revoke is complete. In ext3, this implies calling the
13588 * revoke before clearing the block bitmap when we are deleting
13591 * Revoke performs a journal_forget on any buffer_head passed in as a
13592 * parameter, but does _not_ forget the buffer_head if the bh was only
13593 * found implicitly.
13595 * bh_in may not be a journalled buffer - it may have come off
13596 * the hash tables without an attached journal_head.
13598 * If bh_in is non-zero, journal_revoke() will decrement its b_count
13602 int journal_revoke(handle_t *handle, unsigned long blocknr,
13603 struct buffer_head *bh_in)
13605 struct buffer_head *bh = NULL;
13606 journal_t *journal;
13611 BUFFER_TRACE(bh_in, "enter");
13613 journal = handle->h_transaction->t_journal;
13614 if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)){
13615 J_ASSERT (!"Cannot set revoke feature!");
13619 dev = journal->j_fs_dev;
13623 bh = get_hash_table(dev, blocknr, journal->j_blocksize);
13625 BUFFER_TRACE(bh, "found on hash");
13627 #ifdef JBD_EXPENSIVE_CHECKING
13629 struct buffer_head *bh2;
13631 /* If there is a different buffer_head lying around in
13632 * memory anywhere... */
13633 bh2 = get_hash_table(dev, blocknr, journal->j_blocksize);
13635 /* ... and it has RevokeValid status... */
13637 test_bit(BH_RevokeValid, &bh2->b_state))
13638 /* ...then it better be revoked too,
13639 * since it's illegal to create a revoke
13640 * record against a buffer_head which is
13641 * not marked revoked --- that would
13642 * risk missing a subsequent revoke
13644 J_ASSERT_BH(bh2, test_bit(BH_Revoked, &
13651 /* We really ought not ever to revoke twice in a row without
13652 first having the revoke cancelled: it's illegal to free a
13653 block twice without allocating it in between! */
13655 J_ASSERT_BH(bh, !test_bit(BH_Revoked, &bh->b_state));
13656 set_bit(BH_Revoked, &bh->b_state);
13657 set_bit(BH_RevokeValid, &bh->b_state);
13659 BUFFER_TRACE(bh_in, "call journal_forget");
13660 journal_forget(handle, bh_in);
13662 BUFFER_TRACE(bh, "call brelse");
13667 lock_journal(journal);
13668 jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in);
13669 err = insert_revoke_hash(journal, blocknr,
13670 handle->h_transaction->t_tid);
13671 unlock_journal(journal);
13672 BUFFER_TRACE(bh_in, "exit");
13677 * Cancel an outstanding revoke. For use only internally by the
13678 * journaling code (called from journal_get_write_access).
13680 * We trust the BH_Revoked bit on the buffer if the buffer is already
13681 * being journaled: if there is no revoke pending on the buffer, then we
13682 * don't do anything here.
13684 * This would break if it were possible for a buffer to be revoked and
13685 * discarded, and then reallocated within the same transaction. In such
13686 * a case we would have lost the revoked bit, but when we arrived here
13687 * the second time we would still have a pending revoke to cancel. So,
13688 * do not trust the Revoked bit on buffers unless RevokeValid is also
13691 * The caller must have the journal locked.
13693 int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
13695 struct jbd_revoke_record_s *record;
13696 journal_t *journal = handle->h_transaction->t_journal;
13698 int did_revoke = 0; /* akpm: debug */
13699 struct buffer_head *bh = jh2bh(jh);
13701 jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
13703 /* Is the existing Revoke bit valid? If so, we trust it, and
13704 * only perform the full cancel if the revoke bit is set. If
13705 * not, we can't trust the revoke bit, and we need to do the
13706 * full search for a revoke record. */
13707 if (test_and_set_bit(BH_RevokeValid, &bh->b_state))
13708 need_cancel = (test_and_clear_bit(BH_Revoked, &bh->b_state));
13711 clear_bit(BH_Revoked, &bh->b_state);
13715 record = find_revoke_record(journal, bh->b_blocknr);
13717 jbd_debug(4, "cancelled existing revoke on "
13718 "blocknr %lu\n", bh->b_blocknr);
13719 list_del(&record->hash);
13720 kmem_cache_free(revoke_record_cache, record);
13725 #ifdef JBD_EXPENSIVE_CHECKING
13726 /* There better not be one left behind by now! */
13727 record = find_revoke_record(journal, bh->b_blocknr);
13728 J_ASSERT_JH(jh, record == NULL);
13731 /* Finally, have we just cleared revoke on an unhashed
13732 * buffer_head? If so, we'd better make sure we clear the
13733 * revoked status on any hashed alias too, otherwise the revoke
13734 * state machine will get very upset later on. */
13735 if (need_cancel && !bh->b_pprev) {
13736 struct buffer_head *bh2;
13737 bh2 = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size);
13739 clear_bit(BH_Revoked, &bh2->b_state);
13749 * Write revoke records to the journal for all entries in the current
13750 * revoke hash, deleting the entries as we go.
13752 * Called with the journal lock held.
13755 void journal_write_revoke_records(journal_t *journal,
13756 transaction_t *transaction)
13758 struct journal_head *descriptor;
13759 struct jbd_revoke_record_s *record;
13760 struct jbd_revoke_table_s *revoke;
13761 struct list_head *hash_list;
13762 int i, offset, count;
13767 revoke = journal->j_revoke;
13769 for (i = 0; i < revoke->hash_size; i++) {
13770 hash_list = &revoke->hash_table[i];
13772 while (!list_empty(hash_list)) {
13773 record = (struct jbd_revoke_record_s *)
13775 write_one_revoke_record(journal, transaction,
13776 &descriptor, &offset,
13779 list_del(&record->hash);
13780 kmem_cache_free(revoke_record_cache, record);
13784 flush_descriptor(journal, descriptor, offset);
13785 jbd_debug(1, "Wrote %d revoke records\n", count);
13789 * Write out one revoke record. We need to create a new descriptor
13790 * block if the old one is full or if we have not already created one.
13793 static void write_one_revoke_record(journal_t *journal,
13794 transaction_t *transaction,
13795 struct journal_head **descriptorp,
13797 struct jbd_revoke_record_s *record)
13799 struct journal_head *descriptor;
13801 journal_header_t *header;
13803 /* If we are already aborting, this all becomes a noop. We
13804 still need to go round the loop in
13805 journal_write_revoke_records in order to free all of the
13806 revoke records: only the IO to the journal is omitted. */
13807 if (is_journal_aborted(journal))
13810 descriptor = *descriptorp;
13813 /* Make sure we have a descriptor with space left for the record */
13815 if (offset == journal->j_blocksize) {
13816 flush_descriptor(journal, descriptor, offset);
13822 descriptor = journal_get_descriptor_buffer(journal);
13825 header = (journal_header_t *) &jh2bh(descriptor)->b_data[0];
13826 header->h_magic = htonl(JFS_MAGIC_NUMBER);
13827 header->h_blocktype = htonl(JFS_REVOKE_BLOCK);
13828 header->h_sequence = htonl(transaction->t_tid);
13830 /* Record it so that we can wait for IO completion later */
13831 JBUFFER_TRACE(descriptor, "file as BJ_LogCtl");
13832 journal_file_buffer(descriptor, transaction, BJ_LogCtl);
13834 offset = sizeof(journal_revoke_header_t);
13835 *descriptorp = descriptor;
13838 * ((unsigned int *)(&jh2bh(descriptor)->b_data[offset])) =
13839 htonl(record->blocknr);
13845 * Flush a revoke descriptor out to the journal. If we are aborting,
13846 * this is a noop; otherwise we are generating a buffer which needs to
13847 * be waited for during commit, so it has to go onto the appropriate
13848 * journal buffer list.
13851 static void flush_descriptor(journal_t *journal,
13852 struct journal_head *descriptor,
13855 journal_revoke_header_t *header;
13857 if (is_journal_aborted(journal)) {
13858 JBUFFER_TRACE(descriptor, "brelse");
13859 __brelse(jh2bh(descriptor));
13863 header = (journal_revoke_header_t *) jh2bh(descriptor)->b_data;
13864 header->r_count = htonl(offset);
13865 set_bit(BH_JWrite, &jh2bh(descriptor)->b_state);
13867 struct buffer_head *bh = jh2bh(descriptor);
13868 BUFFER_TRACE(bh, "write");
13869 ll_rw_block (WRITE, 1, &bh);
13876 * Revoke support for recovery.
13878 * Recovery needs to be able to:
13880 * record all revoke records, including the tid of the latest instance
13881 * of each revoke in the journal
13883 * check whether a given block in a given transaction should be replayed
13884 * (ie. has not been revoked by a revoke record in that or a subsequent
13887 * empty the revoke table after recovery.
13891 * First, setting revoke records. We create a new revoke record for
13892 * every block ever revoked in the log as we scan it for recovery, and
13893 * we update the existing records if we find multiple revokes for a
13897 int journal_set_revoke(journal_t *journal,
13898 unsigned long blocknr,
13901 struct jbd_revoke_record_s *record;
13903 record = find_revoke_record(journal, blocknr);
13905 /* If we have multiple occurences, only record the
13906 * latest sequence number in the hashed record */
13907 if (tid_gt(sequence, record->sequence))
13908 record->sequence = sequence;
13911 return insert_revoke_hash(journal, blocknr, sequence);
13915 * Test revoke records. For a given block referenced in the log, has
13916 * that block been revoked? A revoke record with a given transaction
13917 * sequence number revokes all blocks in that transaction and earlier
13918 * ones, but later transactions still need replayed.
13921 int journal_test_revoke(journal_t *journal,
13922 unsigned long blocknr,
13925 struct jbd_revoke_record_s *record;
13927 record = find_revoke_record(journal, blocknr);
13930 if (tid_gt(sequence, record->sequence))
13936 * Finally, once recovery is over, we need to clear the revoke table so
13937 * that it can be reused by the running filesystem.
13940 void journal_clear_revoke(journal_t *journal)
13943 struct list_head *hash_list;
13944 struct jbd_revoke_record_s *record;
13945 struct jbd_revoke_table_s *revoke_var;
13947 revoke_var = journal->j_revoke;
13949 for (i = 0; i < revoke_var->hash_size; i++) {
13950 hash_list = &revoke_var->hash_table[i];
13951 while (!list_empty(hash_list)) {
13952 record = (struct jbd_revoke_record_s*) hash_list->next;
13953 list_del(&record->hash);
13954 kmem_cache_free(revoke_record_cache, record);
13960 * e2fsck.c - superblock checks
13962 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
13965 * This file may be redistributed under the terms of the GNU Public
13970 #define MIN_CHECK 1
13971 #define MAX_CHECK 2
13973 static void check_super_value(e2fsck_t ctx, const char *descr,
13974 unsigned long value, int flags,
13975 unsigned long min_val, unsigned long max_val)
13977 struct problem_context pctx;
13979 if (((flags & MIN_CHECK) && (value < min_val)) ||
13980 ((flags & MAX_CHECK) && (value > max_val))) {
13981 clear_problem_context(&pctx);
13984 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13985 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13990 * This routine may get stubbed out in special compilations of the
13993 #ifndef EXT2_SPECIAL_DEVICE_SIZE
13994 errcode_t e2fsck_get_device_size(e2fsck_t ctx)
13996 return (ext2fs_get_device_size(ctx->filesystem_name,
13997 EXT2_BLOCK_SIZE(ctx->fs->super),
13998 &ctx->num_blocks));
14003 * helper function to release an inode
14005 struct process_block_struct {
14008 struct problem_context *pctx;
14010 int truncate_offset;
14011 e2_blkcnt_t truncate_block;
14012 int truncated_blocks;
14017 static int release_inode_block(ext2_filsys fs,
14019 e2_blkcnt_t blockcnt,
14020 blk_t ref_blk EXT2FS_ATTR((unused)),
14021 int ref_offset EXT2FS_ATTR((unused)),
14024 struct process_block_struct *pb;
14026 struct problem_context *pctx;
14027 blk_t blk = *block_nr;
14030 pb = (struct process_block_struct *) priv_data;
14035 pctx->blkcount = blockcnt;
14037 if (HOLE_BLKADDR(blk))
14040 if ((blk < fs->super->s_first_data_block) ||
14041 (blk >= fs->super->s_blocks_count)) {
14042 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
14045 return BLOCK_ABORT;
14048 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
14049 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
14054 * If we are deleting an orphan, then we leave the fields alone.
14055 * If we are truncating an orphan, then update the inode fields
14056 * and clean up any partial block data.
14058 if (pb->truncating) {
14060 * We only remove indirect blocks if they are
14061 * completely empty.
14063 if (blockcnt < 0) {
14067 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
14072 limit = fs->blocksize >> 2;
14073 for (i = 0, bp = (blk_t *) pb->buf;
14074 i < limit; i++, bp++)
14079 * We don't remove direct blocks until we've reached
14080 * the truncation block.
14082 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
14085 * If part of the last block needs truncating, we do
14088 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
14089 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
14093 memset(pb->buf + pb->truncate_offset, 0,
14094 fs->blocksize - pb->truncate_offset);
14095 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
14100 pb->truncated_blocks++;
14102 retval |= BLOCK_CHANGED;
14105 ext2fs_block_alloc_stats(fs, blk, -1);
14110 * This function releases an inode. Returns 1 if an inconsistency was
14111 * found. If the inode has a link count, then it is being truncated and
14114 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
14115 struct ext2_inode *inode, char *block_buf,
14116 struct problem_context *pctx)
14118 struct process_block_struct pb;
14119 ext2_filsys fs = ctx->fs;
14123 if (!ext2fs_inode_has_valid_blocks(inode))
14126 pb.buf = block_buf + 3 * ctx->fs->blocksize;
14131 if (inode->i_links_count) {
14133 pb.truncate_block = (e2_blkcnt_t)
14134 ((((long long)inode->i_size_high << 32) +
14135 inode->i_size + fs->blocksize - 1) /
14137 pb.truncate_offset = inode->i_size % fs->blocksize;
14140 pb.truncate_block = 0;
14141 pb.truncate_offset = 0;
14143 pb.truncated_blocks = 0;
14144 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
14145 block_buf, release_inode_block, &pb);
14147 com_err("release_inode_blocks", retval,
14148 _("while calling ext2fs_block_iterate for inode %d"),
14155 /* Refresh the inode since ext2fs_block_iterate may have changed it */
14156 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
14158 if (pb.truncated_blocks)
14159 inode->i_blocks -= pb.truncated_blocks *
14160 (fs->blocksize / 512);
14162 if (inode->i_file_acl) {
14163 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
14164 block_buf, -1, &count);
14165 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
14170 com_err("release_inode_blocks", retval,
14171 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
14176 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
14177 inode->i_file_acl = 0;
14183 * This function releases all of the orphan inodes. It returns 1 if
14184 * it hit some error, and 0 on success.
14186 static int release_orphan_inodes(e2fsck_t ctx)
14188 ext2_filsys fs = ctx->fs;
14189 ext2_ino_t ino, next_ino;
14190 struct ext2_inode inode;
14191 struct problem_context pctx;
14194 if ((ino = fs->super->s_last_orphan) == 0)
14198 * Win or lose, we won't be using the head of the orphan inode
14201 fs->super->s_last_orphan = 0;
14202 ext2fs_mark_super_dirty(fs);
14205 * If the filesystem contains errors, don't run the orphan
14206 * list, since the orphan list can't be trusted; and we're
14207 * going to be running a full e2fsck run anyway...
14209 if (fs->super->s_state & EXT2_ERROR_FS)
14212 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
14213 (ino > fs->super->s_inodes_count)) {
14214 clear_problem_context(&pctx);
14216 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
14220 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
14221 "block iterate buffer");
14222 e2fsck_read_bitmaps(ctx);
14225 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
14226 clear_problem_context(&pctx);
14228 pctx.inode = &inode;
14229 pctx.str = inode.i_links_count ? _("Truncating") :
14232 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
14234 next_ino = inode.i_dtime;
14236 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
14237 (next_ino > fs->super->s_inodes_count))) {
14238 pctx.ino = next_ino;
14239 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
14243 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
14246 if (!inode.i_links_count) {
14247 ext2fs_inode_alloc_stats2(fs, ino, -1,
14248 LINUX_S_ISDIR(inode.i_mode));
14249 inode.i_dtime = time(0);
14253 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
14256 ext2fs_free_mem(&block_buf);
14259 ext2fs_free_mem(&block_buf);
14264 * Check the resize inode to make sure it is sane. We check both for
14265 * the case where on-line resizing is not enabled (in which case the
14266 * resize inode should be cleared) as well as the case where on-line
14267 * resizing is enabled.
14269 static void check_resize_inode(e2fsck_t ctx)
14271 ext2_filsys fs = ctx->fs;
14272 struct ext2_inode inode;
14273 struct problem_context pctx;
14274 int i, j, gdt_off, ind_off;
14275 blk_t blk, pblk, expect;
14276 __u32 *dind_buf = 0, *ind_buf;
14279 clear_problem_context(&pctx);
14282 * If the resize inode feature isn't set, then
14283 * s_reserved_gdt_blocks must be zero.
14285 if (!(fs->super->s_feature_compat &
14286 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
14287 if (fs->super->s_reserved_gdt_blocks) {
14288 pctx.num = fs->super->s_reserved_gdt_blocks;
14289 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
14291 fs->super->s_reserved_gdt_blocks = 0;
14292 ext2fs_mark_super_dirty(fs);
14297 /* Read the resizde inode */
14298 pctx.ino = EXT2_RESIZE_INO;
14299 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
14301 if (fs->super->s_feature_compat &
14302 EXT2_FEATURE_COMPAT_RESIZE_INODE)
14303 ctx->flags |= E2F_FLAG_RESIZE_INODE;
14308 * If the resize inode feature isn't set, check to make sure
14309 * the resize inode is cleared; then we're done.
14311 if (!(fs->super->s_feature_compat &
14312 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
14313 for (i=0; i < EXT2_N_BLOCKS; i++) {
14314 if (inode.i_block[i])
14317 if ((i < EXT2_N_BLOCKS) &&
14318 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
14319 memset(&inode, 0, sizeof(inode));
14320 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
14327 * The resize inode feature is enabled; check to make sure the
14328 * only block in use is the double indirect block
14330 blk = inode.i_block[EXT2_DIND_BLOCK];
14331 for (i=0; i < EXT2_N_BLOCKS; i++) {
14332 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
14335 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
14336 !(inode.i_mode & LINUX_S_IFREG) ||
14337 (blk < fs->super->s_first_data_block ||
14338 blk >= fs->super->s_blocks_count)) {
14339 resize_inode_invalid:
14340 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
14341 memset(&inode, 0, sizeof(inode));
14342 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
14344 ctx->flags |= E2F_FLAG_RESIZE_INODE;
14346 if (!(ctx->options & E2F_OPT_READONLY)) {
14347 fs->super->s_state &= ~EXT2_VALID_FS;
14348 ext2fs_mark_super_dirty(fs);
14352 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
14353 "resize dind buffer");
14354 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
14356 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
14358 goto resize_inode_invalid;
14360 gdt_off = fs->desc_blocks;
14361 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
14362 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
14363 i++, gdt_off++, pblk++) {
14364 gdt_off %= fs->blocksize/4;
14365 if (dind_buf[gdt_off] != pblk)
14366 goto resize_inode_invalid;
14367 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
14369 goto resize_inode_invalid;
14371 for (j = 1; j < fs->group_desc_count; j++) {
14372 if (!ext2fs_bg_has_super(fs, j))
14374 expect = pblk + (j * fs->super->s_blocks_per_group);
14375 if (ind_buf[ind_off] != expect)
14376 goto resize_inode_invalid;
14383 ext2fs_free_mem(&dind_buf);
14387 void check_super_block(e2fsck_t ctx)
14389 ext2_filsys fs = ctx->fs;
14390 blk_t first_block, last_block;
14391 struct ext2_super_block *sb = fs->super;
14392 struct ext2_group_desc *gd;
14393 blk_t blocks_per_group = fs->super->s_blocks_per_group;
14395 int inodes_per_block;
14400 struct problem_context pctx;
14401 __u32 free_blocks = 0, free_inodes = 0;
14403 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
14404 ipg_max = inodes_per_block * (blocks_per_group - 4);
14405 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
14406 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
14407 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
14408 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
14409 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
14411 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
14412 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
14413 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
14414 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
14415 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
14416 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
14418 clear_problem_context(&pctx);
14421 * Verify the super block constants...
14423 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
14425 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
14427 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
14428 MAX_CHECK, 0, sb->s_blocks_count);
14429 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
14430 MIN_CHECK | MAX_CHECK, 0,
14431 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
14432 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
14433 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
14434 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
14435 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
14437 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
14438 MIN_CHECK | MAX_CHECK, 8, bpg_max);
14439 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
14440 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
14441 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
14442 MAX_CHECK, 0, sb->s_blocks_count / 2);
14443 check_super_value(ctx, "reserved_gdt_blocks",
14444 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
14446 inode_size = EXT2_INODE_SIZE(sb);
14447 check_super_value(ctx, "inode_size",
14448 inode_size, MIN_CHECK | MAX_CHECK,
14449 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
14450 if (inode_size & (inode_size - 1)) {
14451 pctx.num = inode_size;
14452 pctx.str = "inode_size";
14453 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
14454 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
14458 if (!ctx->num_blocks) {
14459 pctx.errcode = e2fsck_get_device_size(ctx);
14460 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
14461 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
14462 ctx->flags |= E2F_FLAG_ABORT;
14465 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
14466 (ctx->num_blocks < sb->s_blocks_count)) {
14467 pctx.blk = sb->s_blocks_count;
14468 pctx.blk2 = ctx->num_blocks;
14469 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
14470 ctx->flags |= E2F_FLAG_ABORT;
14476 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
14477 pctx.blk = EXT2_BLOCK_SIZE(sb);
14478 pctx.blk2 = EXT2_FRAG_SIZE(sb);
14479 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
14480 ctx->flags |= E2F_FLAG_ABORT;
14484 should_be = sb->s_frags_per_group >>
14485 (sb->s_log_block_size - sb->s_log_frag_size);
14486 if (sb->s_blocks_per_group != should_be) {
14487 pctx.blk = sb->s_blocks_per_group;
14488 pctx.blk2 = should_be;
14489 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
14490 ctx->flags |= E2F_FLAG_ABORT;
14494 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
14495 if (sb->s_first_data_block != should_be) {
14496 pctx.blk = sb->s_first_data_block;
14497 pctx.blk2 = should_be;
14498 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
14499 ctx->flags |= E2F_FLAG_ABORT;
14503 should_be = sb->s_inodes_per_group * fs->group_desc_count;
14504 if (sb->s_inodes_count != should_be) {
14505 pctx.ino = sb->s_inodes_count;
14506 pctx.ino2 = should_be;
14507 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
14508 sb->s_inodes_count = should_be;
14509 ext2fs_mark_super_dirty(fs);
14514 * Verify the group descriptors....
14516 first_block = sb->s_first_data_block;
14517 last_block = first_block + blocks_per_group;
14519 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
14522 if (i == fs->group_desc_count - 1)
14523 last_block = sb->s_blocks_count;
14524 if ((gd->bg_block_bitmap < first_block) ||
14525 (gd->bg_block_bitmap >= last_block)) {
14526 pctx.blk = gd->bg_block_bitmap;
14527 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
14528 gd->bg_block_bitmap = 0;
14530 if (gd->bg_block_bitmap == 0) {
14531 ctx->invalid_block_bitmap_flag[i]++;
14532 ctx->invalid_bitmaps++;
14534 if ((gd->bg_inode_bitmap < first_block) ||
14535 (gd->bg_inode_bitmap >= last_block)) {
14536 pctx.blk = gd->bg_inode_bitmap;
14537 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
14538 gd->bg_inode_bitmap = 0;
14540 if (gd->bg_inode_bitmap == 0) {
14541 ctx->invalid_inode_bitmap_flag[i]++;
14542 ctx->invalid_bitmaps++;
14544 if ((gd->bg_inode_table < first_block) ||
14545 ((gd->bg_inode_table +
14546 fs->inode_blocks_per_group - 1) >= last_block)) {
14547 pctx.blk = gd->bg_inode_table;
14548 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
14549 gd->bg_inode_table = 0;
14551 if (gd->bg_inode_table == 0) {
14552 ctx->invalid_inode_table_flag[i]++;
14553 ctx->invalid_bitmaps++;
14555 free_blocks += gd->bg_free_blocks_count;
14556 free_inodes += gd->bg_free_inodes_count;
14557 first_block += sb->s_blocks_per_group;
14558 last_block += sb->s_blocks_per_group;
14560 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
14561 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
14562 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
14563 ext2fs_unmark_valid(fs);
14568 * Update the global counts from the block group counts. This
14569 * is needed for an experimental patch which eliminates
14570 * locking the entire filesystem when allocating blocks or
14571 * inodes; if the filesystem is not unmounted cleanly, the
14572 * global counts may not be accurate.
14574 if ((free_blocks != sb->s_free_blocks_count) ||
14575 (free_inodes != sb->s_free_inodes_count)) {
14576 if (ctx->options & E2F_OPT_READONLY)
14577 ext2fs_unmark_valid(fs);
14579 sb->s_free_blocks_count = free_blocks;
14580 sb->s_free_inodes_count = free_inodes;
14581 ext2fs_mark_super_dirty(fs);
14585 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
14586 (sb->s_free_inodes_count > sb->s_inodes_count))
14587 ext2fs_unmark_valid(fs);
14591 * If we have invalid bitmaps, set the error state of the
14594 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
14595 sb->s_state &= ~EXT2_VALID_FS;
14596 ext2fs_mark_super_dirty(fs);
14599 clear_problem_context(&pctx);
14601 #ifndef EXT2_SKIP_UUID
14603 * If the UUID field isn't assigned, assign it.
14605 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
14606 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
14607 uuid_generate(sb->s_uuid);
14608 ext2fs_mark_super_dirty(fs);
14609 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
14615 * For the Hurd, check to see if the filetype option is set,
14616 * since it doesn't support it.
14618 if (!(ctx->options & E2F_OPT_READONLY) &&
14619 fs->super->s_creator_os == EXT2_OS_HURD &&
14620 (fs->super->s_feature_incompat &
14621 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
14622 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
14623 fs->super->s_feature_incompat &=
14624 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
14625 ext2fs_mark_super_dirty(fs);
14631 * If we have any of the compatibility flags set, we need to have a
14632 * revision 1 filesystem. Most kernels will not check the flags on
14633 * a rev 0 filesystem and we may have corruption issues because of
14634 * the incompatible changes to the filesystem.
14636 if (!(ctx->options & E2F_OPT_READONLY) &&
14637 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
14638 (fs->super->s_feature_compat ||
14639 fs->super->s_feature_ro_compat ||
14640 fs->super->s_feature_incompat) &&
14641 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
14642 ext2fs_update_dynamic_rev(fs);
14643 ext2fs_mark_super_dirty(fs);
14646 check_resize_inode(ctx);
14649 * Clean up any orphan inodes, if present.
14651 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
14652 fs->super->s_state &= ~EXT2_VALID_FS;
14653 ext2fs_mark_super_dirty(fs);
14657 * Move the ext3 journal file, if necessary.
14659 e2fsck_move_ext3_journal(ctx);
14663 * swapfs.c --- byte-swap an ext2 filesystem
14665 * Copyright 1996, 1997 by Theodore Ts'o
14668 * This file may be redistributed under the terms of the GNU Public
14674 #ifdef ENABLE_SWAPFS
14676 struct swap_block_struct {
14681 struct ext2_inode *inode;
14685 * This is a helper function for block_iterate. We mark all of the
14686 * indirect and direct blocks as changed, so that block_iterate will
14689 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
14694 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
14696 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
14697 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
14699 sb->errcode = retval;
14700 return BLOCK_ABORT;
14702 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
14704 sb->errcode = retval;
14705 return BLOCK_ABORT;
14708 if (blockcnt >= 0) {
14709 if (blockcnt < EXT2_NDIR_BLOCKS)
14711 return BLOCK_CHANGED;
14713 if (blockcnt == BLOCK_COUNT_IND) {
14714 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
14716 return BLOCK_CHANGED;
14718 if (blockcnt == BLOCK_COUNT_DIND) {
14719 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
14721 return BLOCK_CHANGED;
14723 if (blockcnt == BLOCK_COUNT_TIND) {
14724 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
14726 return BLOCK_CHANGED;
14728 return BLOCK_CHANGED;
14732 * This function is responsible for byte-swapping all of the indirect,
14733 * block pointers. It is also responsible for byte-swapping directories.
14735 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
14736 struct ext2_inode *inode)
14739 struct swap_block_struct sb;
14743 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
14746 if (LINUX_S_ISDIR(inode->i_mode))
14749 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
14752 com_err("swap_inode_blocks", retval,
14753 _("while calling ext2fs_block_iterate"));
14754 ctx->flags |= E2F_FLAG_ABORT;
14758 com_err("swap_inode_blocks", sb.errcode,
14759 _("while calling iterator function"));
14760 ctx->flags |= E2F_FLAG_ABORT;
14765 static void swap_inodes(e2fsck_t ctx)
14767 ext2_filsys fs = ctx->fs;
14770 ext2_ino_t ino = 1;
14771 char *buf, *block_buf;
14773 struct ext2_inode * inode;
14775 e2fsck_use_inode_shortcuts(ctx, 1);
14777 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
14780 com_err("swap_inodes", retval,
14781 _("while allocating inode buffer"));
14782 ctx->flags |= E2F_FLAG_ABORT;
14785 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
14786 "block interate buffer");
14787 for (group = 0; group < fs->group_desc_count; group++) {
14788 retval = io_channel_read_blk(fs->io,
14789 fs->group_desc[group].bg_inode_table,
14790 fs->inode_blocks_per_group, buf);
14792 com_err("swap_inodes", retval,
14793 _("while reading inode table (group %d)"),
14795 ctx->flags |= E2F_FLAG_ABORT;
14798 inode = (struct ext2_inode *) buf;
14799 for (i=0; i < fs->super->s_inodes_per_group;
14800 i++, ino++, inode++) {
14801 ctx->stashed_ino = ino;
14802 ctx->stashed_inode = inode;
14804 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
14805 ext2fs_swap_inode(fs, inode, inode, 0);
14808 * Skip deleted files.
14810 if (inode->i_links_count == 0)
14813 if (LINUX_S_ISDIR(inode->i_mode) ||
14814 ((inode->i_block[EXT2_IND_BLOCK] ||
14815 inode->i_block[EXT2_DIND_BLOCK] ||
14816 inode->i_block[EXT2_TIND_BLOCK]) &&
14817 ext2fs_inode_has_valid_blocks(inode)))
14818 swap_inode_blocks(ctx, ino, block_buf, inode);
14820 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14823 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14824 ext2fs_swap_inode(fs, inode, inode, 1);
14826 retval = io_channel_write_blk(fs->io,
14827 fs->group_desc[group].bg_inode_table,
14828 fs->inode_blocks_per_group, buf);
14830 com_err("swap_inodes", retval,
14831 _("while writing inode table (group %d)"),
14833 ctx->flags |= E2F_FLAG_ABORT;
14837 ext2fs_free_mem(&buf);
14838 ext2fs_free_mem(&block_buf);
14839 e2fsck_use_inode_shortcuts(ctx, 0);
14840 ext2fs_flush_icache(fs);
14843 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
14845 * On the PowerPC, the big-endian variant of the ext2 filesystem
14846 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
14847 * of each word. Thus a bitmap with only bit 0 set would be, as
14848 * a string of bytes, 00 00 00 01 00 ...
14849 * To cope with this, we byte-reverse each word of a bitmap if
14850 * we have a big-endian filesystem, that is, if we are *not*
14851 * byte-swapping other word-sized numbers.
14853 #define EXT2_BIG_ENDIAN_BITMAPS
14856 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14857 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
14859 __u32 *p = (__u32 *) bmap->bitmap;
14860 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
14862 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
14863 *p = ext2fs_swab32(*p);
14868 #ifdef ENABLE_SWAPFS
14869 void swap_filesys(e2fsck_t ctx)
14871 ext2_filsys fs = ctx->fs;
14872 #ifdef RESOURCE_TRACK
14873 struct resource_track rtrack;
14875 init_resource_track(&rtrack);
14878 if (!(ctx->options & E2F_OPT_PREEN))
14879 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
14882 mtrace_print("Byte swap");
14885 if (fs->super->s_mnt_count) {
14886 fprintf(stderr, _("%s: the filesystem must be freshly "
14887 "checked using fsck\n"
14888 "and not mounted before trying to "
14889 "byte-swap it.\n"), ctx->device_name);
14890 ctx->flags |= E2F_FLAG_ABORT;
14893 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
14894 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
14895 EXT2_FLAG_SWAP_BYTES_WRITE);
14896 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
14898 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
14899 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
14902 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14904 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14905 fs->flags |= EXT2_FLAG_SWAP_BYTES;
14906 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
14907 EXT2_FLAG_SWAP_BYTES_WRITE);
14909 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14910 e2fsck_read_bitmaps(ctx);
14911 ext2fs_swap_bitmap(fs->inode_map);
14912 ext2fs_swap_bitmap(fs->block_map);
14913 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
14915 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
14917 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
14919 #ifdef RESOURCE_TRACK
14920 if (ctx->options & E2F_OPT_TIME2)
14921 print_resource_track(_("Byte swap"), &rtrack);
14924 #endif /* ENABLE_SWAPFS */
14928 * util.c --- miscellaneous utilities
14930 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
14933 * This file may be redistributed under the terms of the GNU Public
14938 #ifdef HAVE_CONIO_H
14939 #undef HAVE_TERMIOS_H
14941 #define read_a_char() getch()
14943 #ifdef HAVE_TERMIOS_H
14944 #include <termios.h>
14949 void fatal_error(e2fsck_t ctx, const char *msg)
14952 fprintf (stderr, "e2fsck: %s\n", msg);
14953 if (ctx->fs && ctx->fs->io) {
14954 if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
14955 io_channel_flush(ctx->fs->io);
14957 fprintf(stderr, "e2fsck: io manager magic bad!\n");
14959 ctx->flags |= E2F_FLAG_ABORT;
14960 if (ctx->flags & E2F_FLAG_SETJMP_OK)
14961 longjmp(ctx->abort_loc, 1);
14966 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
14967 const char *description)
14972 #ifdef DEBUG_ALLOCATE_MEMORY
14973 printf("Allocating %d bytes for %s...\n", size, description);
14975 ret = malloc(size);
14977 sprintf(buf, "Can't allocate %s\n", description);
14978 fatal_error(ctx, buf);
14980 memset(ret, 0, size);
14984 char *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
14985 const char *str, int len)
14993 ret = malloc(len+1);
14995 strncpy(ret, str, len);
15001 #ifndef HAVE_CONIO_H
15002 static int read_a_char(void)
15009 if (e2fsck_global_ctx &&
15010 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
15013 r = read(0, &c, 1);
15023 int ask_yn(const char * string, int def)
15026 const char *defstr;
15027 const char *short_yes = _("yY");
15028 const char *short_no = _("nN");
15030 #ifdef HAVE_TERMIOS_H
15031 struct termios termios, tmp;
15033 tcgetattr (0, &termios);
15035 tmp.c_lflag &= ~(ICANON | ECHO);
15036 tmp.c_cc[VMIN] = 1;
15037 tmp.c_cc[VTIME] = 0;
15038 tcsetattr (0, TCSANOW, &tmp);
15042 defstr = _(_("<y>"));
15044 defstr = _(_("<n>"));
15046 defstr = _(" (y/n)");
15047 printf("%s%s? ", string, defstr);
15050 if ((c = read_a_char()) == EOF)
15053 #ifdef HAVE_TERMIOS_H
15054 tcsetattr (0, TCSANOW, &termios);
15056 if (e2fsck_global_ctx &&
15057 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
15059 longjmp(e2fsck_global_ctx->abort_loc, 1);
15061 puts(_("cancelled!\n"));
15064 if (strchr(short_yes, (char) c)) {
15068 else if (strchr(short_no, (char) c)) {
15072 else if ((c == ' ' || c == '\n') && (def != -1))
15079 #ifdef HAVE_TERMIOS_H
15080 tcsetattr (0, TCSANOW, &termios);
15085 int ask (e2fsck_t ctx, const char * string, int def)
15087 if (ctx->options & E2F_OPT_NO) {
15088 printf (_("%s? no\n\n"), string);
15091 if (ctx->options & E2F_OPT_YES) {
15092 printf (_("%s? yes\n\n"), string);
15095 if (ctx->options & E2F_OPT_PREEN) {
15096 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
15099 return ask_yn(string, def);
15102 void e2fsck_read_bitmaps(e2fsck_t ctx)
15104 ext2_filsys fs = ctx->fs;
15107 if (ctx->invalid_bitmaps) {
15108 com_err(ctx->program_name, 0,
15109 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
15111 fatal_error(ctx, 0);
15114 ehandler_operation(_("reading inode and block bitmaps"));
15115 retval = ext2fs_read_bitmaps(fs);
15116 ehandler_operation(0);
15118 com_err(ctx->program_name, retval,
15119 _("while retrying to read bitmaps for %s"),
15121 fatal_error(ctx, 0);
15125 void e2fsck_write_bitmaps(e2fsck_t ctx)
15127 ext2_filsys fs = ctx->fs;
15130 if (ext2fs_test_bb_dirty(fs)) {
15131 ehandler_operation(_("writing block bitmaps"));
15132 retval = ext2fs_write_block_bitmap(fs);
15133 ehandler_operation(0);
15135 com_err(ctx->program_name, retval,
15136 _("while retrying to write block bitmaps for %s"),
15138 fatal_error(ctx, 0);
15142 if (ext2fs_test_ib_dirty(fs)) {
15143 ehandler_operation(_("writing inode bitmaps"));
15144 retval = ext2fs_write_inode_bitmap(fs);
15145 ehandler_operation(0);
15147 com_err(ctx->program_name, retval,
15148 _("while retrying to write inode bitmaps for %s"),
15150 fatal_error(ctx, 0);
15155 void preenhalt(e2fsck_t ctx)
15157 ext2_filsys fs = ctx->fs;
15159 if (!(ctx->options & E2F_OPT_PREEN))
15161 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
15162 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
15165 fs->super->s_state |= EXT2_ERROR_FS;
15166 ext2fs_mark_super_dirty(fs);
15169 exit(FSCK_UNCORRECTED);
15172 #ifdef RESOURCE_TRACK
15173 void init_resource_track(struct resource_track *track)
15175 #ifdef HAVE_GETRUSAGE
15179 track->brk_start = sbrk(0);
15180 gettimeofday(&track->time_start, 0);
15181 #ifdef HAVE_GETRUSAGE
15183 memset(&r, 0, sizeof(struct rusage));
15185 getrusage(RUSAGE_SELF, &r);
15186 track->user_start = r.ru_utime;
15187 track->system_start = r.ru_stime;
15189 track->user_start.tv_sec = track->user_start.tv_usec = 0;
15190 track->system_start.tv_sec = track->system_start.tv_usec = 0;
15194 static _INLINE_ float timeval_subtract(struct timeval *tv1,
15195 struct timeval *tv2)
15197 return ((tv1->tv_sec - tv2->tv_sec) +
15198 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
15201 void print_resource_track(const char *desc, struct resource_track *track)
15203 #ifdef HAVE_GETRUSAGE
15206 #ifdef HAVE_MALLINFO
15207 struct mallinfo malloc_info;
15209 struct timeval time_end;
15211 gettimeofday(&time_end, 0);
15214 printf("%s: ", desc);
15216 #ifdef HAVE_MALLINFO
15217 #define kbytes(x) (((x) + 1023) / 1024)
15219 malloc_info = mallinfo();
15220 printf(_("Memory used: %dk/%dk (%dk/%dk), "),
15221 kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
15222 kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
15224 printf(_("Memory used: %d, "),
15225 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
15227 #ifdef HAVE_GETRUSAGE
15228 getrusage(RUSAGE_SELF, &r);
15230 printf(_("time: %5.2f/%5.2f/%5.2f\n"),
15231 timeval_subtract(&time_end, &track->time_start),
15232 timeval_subtract(&r.ru_utime, &track->user_start),
15233 timeval_subtract(&r.ru_stime, &track->system_start));
15235 printf(_("elapsed time: %6.3f\n"),
15236 timeval_subtract(&time_end, &track->time_start));
15239 #endif /* RESOURCE_TRACK */
15241 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
15242 struct ext2_inode * inode, const char *proc)
15246 retval = ext2fs_read_inode(ctx->fs, ino, inode);
15248 com_err("ext2fs_read_inode", retval,
15249 _("while reading inode %ld in %s"), ino, proc);
15250 fatal_error(ctx, 0);
15254 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
15255 struct ext2_inode * inode, int bufsize,
15260 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
15262 com_err("ext2fs_write_inode", retval,
15263 _("while writing inode %ld in %s"), ino, proc);
15264 fatal_error(ctx, 0);
15268 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
15269 struct ext2_inode * inode, const char *proc)
15273 retval = ext2fs_write_inode(ctx->fs, ino, inode);
15275 com_err("ext2fs_write_inode", retval,
15276 _("while writing inode %ld in %s"), ino, proc);
15277 fatal_error(ctx, 0);
15282 void mtrace_print(char *mesg)
15284 FILE *malloc_get_mallstream();
15285 FILE *f = malloc_get_mallstream();
15288 fprintf(f, "============= %s\n", mesg);
15292 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
15293 io_manager manager)
15295 struct ext2_super_block *sb;
15296 io_channel io = NULL;
15299 blk_t superblock, ret_sb = 8193;
15301 if (fs && fs->super) {
15302 ret_sb = (fs->super->s_blocks_per_group +
15303 fs->super->s_first_data_block);
15305 ctx->superblock = ret_sb;
15306 ctx->blocksize = fs->blocksize;
15312 if (ctx->blocksize) {
15313 ret_sb = ctx->blocksize * 8;
15314 if (ctx->blocksize == 1024)
15316 ctx->superblock = ret_sb;
15319 ctx->superblock = ret_sb;
15320 ctx->blocksize = 1024;
15323 if (!name || !manager)
15326 if (manager->open(name, 0, &io) != 0)
15329 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
15331 sb = (struct ext2_super_block *) buf;
15333 for (blocksize = EXT2_MIN_BLOCK_SIZE;
15334 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
15335 superblock = blocksize*8;
15336 if (blocksize == 1024)
15338 io_channel_set_blksize(io, blocksize);
15339 if (io_channel_read_blk(io, superblock,
15340 -SUPERBLOCK_SIZE, buf))
15342 #ifdef EXT2FS_ENABLE_SWAPFS
15343 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
15344 ext2fs_swap_super(sb);
15346 if (sb->s_magic == EXT2_SUPER_MAGIC) {
15347 ret_sb = superblock;
15349 ctx->superblock = superblock;
15350 ctx->blocksize = blocksize;
15358 io_channel_close(io);
15360 ext2fs_free_mem(&buf);
15365 * Given a mode, return the ext2 file type
15367 int ext2_file_type(unsigned int mode)
15369 if (LINUX_S_ISREG(mode))
15370 return EXT2_FT_REG_FILE;
15372 if (LINUX_S_ISDIR(mode))
15373 return EXT2_FT_DIR;
15375 if (LINUX_S_ISCHR(mode))
15376 return EXT2_FT_CHRDEV;
15378 if (LINUX_S_ISBLK(mode))
15379 return EXT2_FT_BLKDEV;
15381 if (LINUX_S_ISLNK(mode))
15382 return EXT2_FT_SYMLINK;
15384 if (LINUX_S_ISFIFO(mode))
15385 return EXT2_FT_FIFO;
15387 if (LINUX_S_ISSOCK(mode))
15388 return EXT2_FT_SOCK;
15393 * unix.c - The unix-specific code for e2fsck
15395 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
15398 * This file may be redistributed under the terms of the GNU Public
15405 /* Command line options */
15407 #ifdef ENABLE_SWAPFS
15408 static int normalize_swapfs;
15410 static int cflag; /* check disk */
15411 static int show_version_only;
15412 static int verbose;
15414 static int replace_bad_blocks;
15415 static int keep_bad_blocks;
15416 static char *bad_blocks_file;
15418 #ifdef __CONFIG_JBD_DEBUG__E2FS /* Enabled by configure --enable-jfs-debug */
15419 int journal_enable_debug = -1;
15423 static void usage(e2fsck_t ctx)
15426 _("Usage: %s [-panyrcdfvstDFSV] [-b superblock] [-B blocksize]\n"
15427 "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
15428 "\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal]\n"
15429 "\t\t[-E extended-options] device\n"),
15430 ctx->program_name);
15432 fprintf(stderr, _("\nEmergency help:\n"
15433 " -p Automatic repair (no questions)\n"
15434 " -n Make no changes to the filesystem\n"
15435 " -y Assume \"yes\" to all questions\n"
15436 " -c Check for bad blocks and add them to the badblock list\n"
15437 " -f Force checking even if filesystem is marked clean\n"));
15438 fprintf(stderr, _(""
15440 " -b superblock Use alternative superblock\n"
15441 " -B blocksize Force blocksize when looking for superblock\n"
15442 " -j external-journal Set location of the external journal\n"
15443 " -l bad_blocks_file Add to badblocks list\n"
15444 " -L bad_blocks_file Set badblocks list\n"
15451 static void show_stats(e2fsck_t ctx)
15453 ext2_filsys fs = ctx->fs;
15454 int inodes, inodes_used, blocks, blocks_used;
15456 int num_files, num_links;
15459 dir_links = 2 * ctx->fs_directory_count - 1;
15460 num_files = ctx->fs_total_count - dir_links;
15461 num_links = ctx->fs_links_count - dir_links;
15462 inodes = fs->super->s_inodes_count;
15463 inodes_used = (fs->super->s_inodes_count -
15464 fs->super->s_free_inodes_count);
15465 blocks = fs->super->s_blocks_count;
15466 blocks_used = (fs->super->s_blocks_count -
15467 fs->super->s_free_blocks_count);
15469 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
15470 frag_percent = (frag_percent + 5) / 10;
15473 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
15474 ctx->device_name, inodes_used, inodes,
15475 frag_percent / 10, frag_percent % 10,
15476 blocks_used, blocks);
15479 printf (P_("\n%8d inode used (%d%%)\n", "\n%8d inodes used (%d%%)\n",
15480 inodes_used), inodes_used, 100 * inodes_used / inodes);
15481 printf (P_("%8d non-contiguous inode (%0d.%d%%)\n",
15482 "%8d non-contiguous inodes (%0d.%d%%)\n",
15483 ctx->fs_fragmented),
15484 ctx->fs_fragmented, frag_percent / 10, frag_percent % 10);
15485 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
15486 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
15487 printf (P_("%8d block used (%d%%)\n", "%8d blocks used (%d%%)\n",
15489 blocks_used, (int) ((long long) 100 * blocks_used / blocks));
15490 printf (P_("%8d bad block\n", "%8d bad blocks\n",
15491 ctx->fs_badblocks_count), ctx->fs_badblocks_count);
15492 printf (P_("%8d large file\n", "%8d large files\n",
15493 ctx->large_files), ctx->large_files);
15494 printf (P_("\n%8d regular file\n", "\n%8d regular files\n",
15495 ctx->fs_regular_count), ctx->fs_regular_count);
15496 printf (P_("%8d directory\n", "%8d directories\n",
15497 ctx->fs_directory_count), ctx->fs_directory_count);
15498 printf (P_("%8d character device file\n",
15499 "%8d character device files\n", ctx->fs_chardev_count),
15500 ctx->fs_chardev_count);
15501 printf (P_("%8d block device file\n", "%8d block device files\n",
15502 ctx->fs_blockdev_count), ctx->fs_blockdev_count);
15503 printf (P_("%8d fifo\n", "%8d fifos\n", ctx->fs_fifo_count),
15504 ctx->fs_fifo_count);
15505 printf (P_("%8d link\n", "%8d links\n",
15506 ctx->fs_links_count - dir_links),
15507 ctx->fs_links_count - dir_links);
15508 printf (P_("%8d symbolic link", "%8d symbolic links",
15509 ctx->fs_symlinks_count), ctx->fs_symlinks_count);
15510 printf (P_(" (%d fast symbolic link)\n", " (%d fast symbolic links)\n",
15511 ctx->fs_fast_symlinks_count), ctx->fs_fast_symlinks_count);
15512 printf (P_("%8d socket\n", "%8d sockets\n", ctx->fs_sockets_count),
15513 ctx->fs_sockets_count);
15514 printf ("--------\n");
15515 printf (P_("%8d file\n", "%8d files\n",
15516 ctx->fs_total_count - dir_links),
15517 ctx->fs_total_count - dir_links);
15520 static void check_mount(e2fsck_t ctx)
15525 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
15526 &ctx->mount_flags);
15528 com_err("ext2fs_check_if_mount", retval,
15529 _("while determining whether %s is mounted."),
15530 ctx->filesystem_name);
15535 * If the filesystem isn't mounted, or it's the root filesystem
15536 * and it's mounted read-only, then everything's fine.
15538 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
15539 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
15540 (ctx->mount_flags & EXT2_MF_READONLY)))
15543 if (ctx->options & E2F_OPT_READONLY) {
15544 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
15548 printf(_("%s is mounted. "), ctx->filesystem_name);
15549 if (!ctx->interactive)
15550 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
15551 printf(_("\n\n\007\007\007\007WARNING!!! "
15552 "Running e2fsck on a mounted filesystem may cause\n"
15553 "SEVERE filesystem damage.\007\007\007\n\n"));
15554 cont = ask_yn(_("Do you really want to continue"), -1);
15556 printf (_("check aborted.\n"));
15562 static int is_on_batt(void)
15566 char tmp[80], tmp2[80], fname[80];
15567 unsigned int acflag;
15570 f = fopen("/proc/apm", "r");
15572 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
15575 return (acflag != 1);
15577 d = opendir("/proc/acpi/ac_adapter");
15579 while ((de=readdir(d)) != NULL) {
15580 if (!strncmp(".", de->d_name, 1))
15582 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
15584 f = fopen(fname, "r");
15587 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
15590 if (strncmp(tmp, "off-line", 8) == 0) {
15601 * This routine checks to see if a filesystem can be skipped; if so,
15602 * it will exit with E2FSCK_OK. Under some conditions it will print a
15603 * message explaining why a check is being forced.
15605 static void check_if_skip(e2fsck_t ctx)
15607 ext2_filsys fs = ctx->fs;
15608 const char *reason = NULL;
15609 unsigned int reason_arg = 0;
15611 int batt = is_on_batt();
15612 time_t now = time(0);
15614 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
15618 if ((fs->super->s_state & EXT2_ERROR_FS) ||
15619 !ext2fs_test_valid(fs))
15620 reason = _(" contains a file system with errors");
15621 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
15622 reason = _(" was not cleanly unmounted");
15623 else if ((fs->super->s_max_mnt_count > 0) &&
15624 (fs->super->s_mnt_count >=
15625 (unsigned) fs->super->s_max_mnt_count)) {
15626 reason = _(" has been mounted %u times without being checked");
15627 reason_arg = fs->super->s_mnt_count;
15628 if (batt && (fs->super->s_mnt_count <
15629 (unsigned) fs->super->s_max_mnt_count*2))
15631 } else if (fs->super->s_checkinterval &&
15632 ((now - fs->super->s_lastcheck) >=
15633 fs->super->s_checkinterval)) {
15634 reason = _(" has gone %u days without being checked");
15635 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
15636 if (batt && ((now - fs->super->s_lastcheck) <
15637 fs->super->s_checkinterval*2))
15641 fputs(ctx->device_name, stdout);
15642 printf(reason, reason_arg);
15643 fputs(_(", check forced.\n"), stdout);
15646 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
15647 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
15648 fs->super->s_inodes_count,
15649 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
15650 fs->super->s_blocks_count);
15651 next_check = 100000;
15652 if (fs->super->s_max_mnt_count > 0) {
15653 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
15654 if (next_check <= 0)
15657 if (fs->super->s_checkinterval &&
15658 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
15660 if (next_check <= 5) {
15661 if (next_check == 1)
15662 fputs(_(" (check after next mount)"), stdout);
15664 printf(_(" (check in %ld mounts)"), next_check);
15666 fputc('\n', stdout);
15669 e2fsck_free_context(ctx);
15674 * For completion notice
15676 struct percent_tbl {
15680 static struct percent_tbl e2fsck_tbl = {
15681 5, { 0, 70, 90, 92, 95, 100 }
15683 static char bar[128], spaces[128];
15685 static float calc_percent(struct percent_tbl *tbl, int pass, int curr,
15692 if (pass > tbl->max_pass || max == 0)
15694 percent = ((float) curr) / ((float) max);
15695 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
15696 + tbl->table[pass-1]);
15699 extern void e2fsck_clear_progbar(e2fsck_t ctx)
15701 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
15704 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
15707 ctx->flags &= ~E2F_FLAG_PROG_BAR;
15710 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
15711 unsigned int dpynum)
15713 static const char spinner[] = "\\|/-";
15720 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
15724 * Calculate the new progress position. If the
15725 * percentage hasn't changed, then we skip out right
15728 fixed_percent = (int) ((10 * percent) + 0.5);
15729 if (ctx->progress_last_percent == fixed_percent)
15731 ctx->progress_last_percent = fixed_percent;
15734 * If we've already updated the spinner once within
15735 * the last 1/8th of a second, no point doing it
15738 gettimeofday(&tv, NULL);
15739 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
15740 if ((tick == ctx->progress_last_time) &&
15741 (fixed_percent != 0) && (fixed_percent != 1000))
15743 ctx->progress_last_time = tick;
15746 * Advance the spinner, and note that the progress bar
15747 * will be on the screen
15749 ctx->progress_pos = (ctx->progress_pos+1) & 3;
15750 ctx->flags |= E2F_FLAG_PROG_BAR;
15752 dpywidth = 66 - strlen(label);
15753 dpywidth = 8 * (dpywidth / 8);
15757 i = ((percent * dpywidth) + 50) / 100;
15758 printf("%s%s: |%s%s", ctx->start_meta, label,
15759 bar + (sizeof(bar) - (i+1)),
15760 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
15761 if (fixed_percent == 1000)
15762 fputc('|', stdout);
15764 fputc(spinner[ctx->progress_pos & 3], stdout);
15765 printf(" %4.1f%% ", percent);
15767 printf("%u\r", dpynum);
15769 fputs(" \r", stdout);
15770 fputs(ctx->stop_meta, stdout);
15772 if (fixed_percent == 1000)
15773 e2fsck_clear_progbar(ctx);
15779 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
15780 unsigned long cur, unsigned long max)
15788 if (ctx->progress_fd) {
15789 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
15790 write(ctx->progress_fd, buf, strlen(buf));
15792 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
15793 e2fsck_simple_progress(ctx, ctx->device_name,
15799 #define PATH_SET "PATH=/sbin"
15801 static void reserve_stdio_fds(void)
15806 fd = open("/dev/null", O_RDWR);
15810 fprintf(stderr, _("ERROR: Couldn't open "
15811 "/dev/null (%s)\n"),
15819 static void signal_progress_on(int sig EXT2FS_ATTR((unused)))
15821 e2fsck_t ctx = e2fsck_global_ctx;
15826 ctx->progress = e2fsck_update_progress;
15827 ctx->progress_fd = 0;
15830 static void signal_progress_off(int sig EXT2FS_ATTR((unused)))
15832 e2fsck_t ctx = e2fsck_global_ctx;
15837 e2fsck_clear_progbar(ctx);
15841 static void signal_cancel(int sig EXT2FS_ATTR((unused)))
15843 e2fsck_t ctx = e2fsck_global_ctx;
15846 exit(FSCK_CANCELED);
15848 ctx->flags |= E2F_FLAG_CANCEL;
15851 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
15853 char *buf, *token, *next, *p, *arg;
15855 int extended_usage = 0;
15857 buf = string_copy(ctx, opts, 0);
15858 for (token = buf; token && *token; token = next) {
15859 p = strchr(token, ',');
15865 arg = strchr(token, '=');
15870 if (strcmp(token, "ea_ver") == 0) {
15875 ea_ver = strtoul(arg, &p, 0);
15877 ((ea_ver != 1) && (ea_ver != 2))) {
15879 _("Invalid EA version.\n"));
15883 ctx->ext_attr_ver = ea_ver;
15887 if (extended_usage) {
15888 fprintf(stderr, _("Extended options are separated by commas, "
15889 "and may take an argument which\n"
15890 "is set off by an equals ('=') sign. "
15891 "Valid raid options are:\n"
15892 "\tea_ver=<ea_version (1 or 2)\n\n"));
15898 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
15903 extern void *mallwatch;
15907 struct sigaction sa;
15908 char *extended_opts = 0;
15910 retval = e2fsck_allocate_context(&ctx);
15916 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
15917 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
15918 if (isatty(0) && isatty(1)) {
15919 ctx->interactive = 1;
15921 ctx->start_meta[0] = '\001';
15922 ctx->stop_meta[0] = '\002';
15924 memset(bar, '=', sizeof(bar)-1);
15925 memset(spaces, ' ', sizeof(spaces)-1);
15926 blkid_get_cache(&ctx->blkid, NULL);
15929 ctx->program_name = *argv;
15931 ctx->program_name = "e2fsck";
15932 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
15935 ctx->progress = e2fsck_update_progress;
15936 ctx->progress_fd = atoi(optarg);
15937 if (!ctx->progress_fd)
15939 /* Validate the file descriptor to avoid disasters */
15940 fd = dup(ctx->progress_fd);
15943 _("Error validating file descriptor %d: %s\n"),
15945 error_message(errno));
15947 _("Invalid completion information file descriptor"));
15952 ctx->options |= E2F_OPT_COMPRESS_DIRS;
15955 extended_opts = optarg;
15959 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
15962 _("Only one the options -p/-a, -n or -y may be specified."));
15964 ctx->options |= E2F_OPT_PREEN;
15967 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
15969 ctx->options |= E2F_OPT_NO;
15972 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
15974 ctx->options |= E2F_OPT_YES;
15977 #ifdef RESOURCE_TRACK
15978 if (ctx->options & E2F_OPT_TIME)
15979 ctx->options |= E2F_OPT_TIME2;
15981 ctx->options |= E2F_OPT_TIME;
15983 fprintf(stderr, _("The -t option is not "
15984 "supported on this version of e2fsck.\n"));
15989 ctx->options |= E2F_OPT_WRITECHECK;
15990 ctx->options |= E2F_OPT_CHECKBLOCKS;
15993 /* What we do by default, anyway! */
15996 ctx->use_superblock = atoi(optarg);
15997 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
16000 ctx->blocksize = atoi(optarg);
16003 ctx->inode_buffer_blocks = atoi(optarg);
16006 ctx->journal_name = string_copy(ctx, optarg, 0);
16009 ctx->process_inode_size = atoi(optarg);
16012 replace_bad_blocks++;
16014 bad_blocks_file = string_copy(ctx, optarg, 0);
16017 ctx->options |= E2F_OPT_DEBUG;
16020 ctx->options |= E2F_OPT_FORCE;
16029 show_version_only = 1;
16033 mallwatch = (void *) strtol(optarg, NULL, 0);
16037 ctx->device_name = optarg;
16039 #ifdef ENABLE_SWAPFS
16041 normalize_swapfs = 1;
16048 fprintf(stderr, _("Byte-swapping filesystems "
16049 "not compiled in this version "
16059 if (show_version_only)
16061 if (optind != argc - 1)
16063 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
16064 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
16065 ctx->options |= E2F_OPT_READONLY;
16066 ctx->io_options = strchr(argv[optind], '?');
16067 if (ctx->io_options)
16068 *ctx->io_options++ = 0;
16069 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
16070 if (!ctx->filesystem_name) {
16071 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
16073 fatal_error(ctx, 0);
16076 parse_extended_opts(ctx, extended_opts);
16079 fd = open(ctx->filesystem_name, O_RDONLY, 0);
16081 com_err("open", errno,
16082 _("while opening %s for flushing"),
16083 ctx->filesystem_name);
16084 fatal_error(ctx, 0);
16086 if ((retval = ext2fs_sync_device(fd, 1))) {
16087 com_err("ext2fs_sync_device", retval,
16088 _("while trying to flush %s"),
16089 ctx->filesystem_name);
16090 fatal_error(ctx, 0);
16094 #ifdef ENABLE_SWAPFS
16096 if (cflag || bad_blocks_file) {
16097 fprintf(stderr, _("Incompatible options not "
16098 "allowed when byte-swapping.\n"));
16103 if (cflag && bad_blocks_file) {
16104 fprintf(stderr, _("The -c and the -l/-L options may "
16105 "not be both used at the same time.\n"));
16109 * Set up signal action
16111 memset(&sa, 0, sizeof(struct sigaction));
16112 sa.sa_handler = signal_cancel;
16113 sigaction(SIGINT, &sa, 0);
16114 sigaction(SIGTERM, &sa, 0);
16116 sa.sa_flags = SA_RESTART;
16118 e2fsck_global_ctx = ctx;
16119 sa.sa_handler = signal_progress_on;
16120 sigaction(SIGUSR1, &sa, 0);
16121 sa.sa_handler = signal_progress_off;
16122 sigaction(SIGUSR2, &sa, 0);
16124 /* Update our PATH to include /sbin if we need to run badblocks */
16126 char *oldpath = getenv("PATH");
16130 newpath = (char *) malloc(sizeof (PATH_SET) + 1 +
16133 fatal_error(ctx, "Couldn't malloc() newpath");
16134 strcpy (newpath, PATH_SET);
16135 strcat (newpath, ":");
16136 strcat (newpath, oldpath);
16141 #ifdef __CONFIG_JBD_DEBUG__E2FS
16142 if (getenv("E2FSCK_JBD_DEBUG"))
16143 journal_enable_debug = atoi(getenv("E2FSCK_JBD_DEBUG"));
16148 static const char *my_ver_string = E2FSPROGS_VERSION;
16149 static const char *my_ver_date = E2FSPROGS_DATE;
16151 int e2fsck_main (int argc, char *argv[])
16153 errcode_t retval = 0;
16154 int exit_value = FSCK_OK;
16155 ext2_filsys fs = 0;
16157 struct ext2_super_block *sb;
16158 const char *lib_ver_date;
16159 int my_ver, lib_ver;
16161 struct problem_context pctx;
16162 int flags, run_result;
16164 clear_problem_context(&pctx);
16172 setlocale(LC_MESSAGES, "");
16173 setlocale(LC_CTYPE, "");
16174 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
16175 textdomain(NLS_CAT_NAME);
16177 my_ver = ext2fs_parse_version_string(my_ver_string);
16178 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
16179 if (my_ver > lib_ver) {
16180 fprintf( stderr, _("Error: ext2fs library version "
16181 "out of date!\n"));
16182 show_version_only++;
16185 retval = PRS(argc, argv, &ctx);
16187 com_err("e2fsck", retval,
16188 _("while trying to initialize program"));
16191 reserve_stdio_fds();
16193 #ifdef RESOURCE_TRACK
16194 init_resource_track(&ctx->global_rtrack);
16197 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
16198 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
16201 if (show_version_only) {
16202 fprintf(stderr, _("\tUsing %s, %s\n"),
16203 error_message(EXT2_ET_BASE), lib_ver_date);
16209 if (!(ctx->options & E2F_OPT_PREEN) &&
16210 !(ctx->options & E2F_OPT_NO) &&
16211 !(ctx->options & E2F_OPT_YES)) {
16212 if (!ctx->interactive)
16214 _("need terminal for interactive repairs"));
16216 ctx->superblock = ctx->use_superblock;
16218 #ifdef CONFIG_TESTIO_DEBUG
16219 io_ptr = test_io_manager;
16220 test_io_backing_manager = unix_io_manager;
16222 io_ptr = unix_io_manager;
16225 if ((ctx->options & E2F_OPT_READONLY) == 0)
16226 flags |= EXT2_FLAG_RW;
16228 if (ctx->superblock && ctx->blocksize) {
16229 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
16230 flags, ctx->superblock, ctx->blocksize,
16232 } else if (ctx->superblock) {
16234 for (blocksize = EXT2_MIN_BLOCK_SIZE;
16235 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
16236 retval = ext2fs_open2(ctx->filesystem_name,
16237 ctx->io_options, flags,
16238 ctx->superblock, blocksize,
16244 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
16245 flags, 0, 0, io_ptr, &fs);
16246 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
16247 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
16248 ((retval == EXT2_ET_BAD_MAGIC) ||
16249 ((retval == 0) && ext2fs_check_desc(fs)))) {
16250 if (!fs || (fs->group_desc_count > 1)) {
16251 printf(_("%s trying backup blocks...\n"),
16252 retval ? _("Couldn't find ext2 superblock,") :
16253 _("Group descriptors look bad..."));
16254 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
16261 com_err(ctx->program_name, retval, _("while trying to open %s"),
16262 ctx->filesystem_name);
16263 if (retval == EXT2_ET_REV_TOO_HIGH) {
16264 printf(_("The filesystem revision is apparently "
16265 "too high for this version of e2fsck.\n"
16266 "(Or the filesystem superblock "
16267 "is corrupt)\n\n"));
16268 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
16269 } else if (retval == EXT2_ET_SHORT_READ)
16270 printf(_("Could this be a zero-length partition?\n"));
16271 else if ((retval == EPERM) || (retval == EACCES))
16272 printf(_("You must have %s access to the "
16273 "filesystem or be root\n"),
16274 (ctx->options & E2F_OPT_READONLY) ?
16276 else if (retval == ENXIO)
16277 printf(_("Possibly non-existent or swap device?\n"));
16279 else if (retval == EROFS)
16280 printf(_("Disk write-protected; use the -n option "
16281 "to do a read-only\n"
16282 "check of the device.\n"));
16285 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
16286 fatal_error(ctx, 0);
16289 fs->priv_data = ctx;
16291 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
16292 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
16293 _("while trying to open %s"),
16294 ctx->filesystem_name);
16296 fatal_error(ctx, _("Get a newer version of e2fsck!"));
16300 * Set the device name, which is used whenever we print error
16301 * or informational messages to the user.
16303 if (ctx->device_name == 0 &&
16304 (sb->s_volume_name[0] != 0)) {
16305 ctx->device_name = string_copy(ctx, sb->s_volume_name,
16306 sizeof(sb->s_volume_name));
16308 if (ctx->device_name == 0)
16309 ctx->device_name = ctx->filesystem_name;
16312 * Make sure the ext3 superblock fields are consistent.
16314 retval = e2fsck_check_ext3_journal(ctx);
16316 com_err(ctx->program_name, retval,
16317 _("while checking ext3 journal for %s"),
16319 fatal_error(ctx, 0);
16323 * Check to see if we need to do ext3-style recovery. If so,
16324 * do it, and then restart the fsck.
16326 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
16327 if (ctx->options & E2F_OPT_READONLY) {
16328 printf(_("Warning: skipping journal recovery "
16329 "because doing a read-only filesystem "
16331 io_channel_flush(ctx->fs->io);
16333 if (ctx->flags & E2F_FLAG_RESTARTED) {
16335 * Whoops, we attempted to run the
16336 * journal twice. This should never
16337 * happen, unless the hardware or
16338 * device driver is being bogus.
16340 com_err(ctx->program_name, 0,
16341 _("unable to set superblock flags on %s\n"), ctx->device_name);
16342 fatal_error(ctx, 0);
16344 retval = e2fsck_run_ext3_journal(ctx);
16346 com_err(ctx->program_name, retval,
16347 _("while recovering ext3 journal of %s"),
16349 fatal_error(ctx, 0);
16351 ext2fs_close(ctx->fs);
16353 ctx->flags |= E2F_FLAG_RESTARTED;
16359 * Check for compatibility with the feature sets. We need to
16360 * be more stringent than ext2fs_open().
16362 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
16363 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
16364 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
16365 "(%s)", ctx->device_name);
16368 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
16369 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
16370 "(%s)", ctx->device_name);
16373 #ifdef ENABLE_COMPRESSION
16374 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
16375 com_err(ctx->program_name, 0,
16376 _("Warning: compression support is experimental.\n"));
16378 #ifndef ENABLE_HTREE
16379 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
16380 com_err(ctx->program_name, 0,
16381 _("E2fsck not compiled with HTREE support,\n\t"
16382 "but filesystem %s has HTREE directories.\n"),
16389 * If the user specified a specific superblock, presumably the
16390 * master superblock has been trashed. So we mark the
16391 * superblock as dirty, so it can be written out.
16393 if (ctx->superblock &&
16394 !(ctx->options & E2F_OPT_READONLY))
16395 ext2fs_mark_super_dirty(fs);
16398 * We only update the master superblock because (a) paranoia;
16399 * we don't want to corrupt the backup superblocks, and (b) we
16400 * don't need to update the mount count and last checked
16401 * fields in the backup superblock (the kernel doesn't
16402 * update the backup superblocks anyway).
16404 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
16406 ehandler_init(fs->io);
16408 if (ctx->superblock)
16409 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
16410 ext2fs_mark_valid(fs);
16411 check_super_block(ctx);
16412 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16413 fatal_error(ctx, 0);
16414 check_if_skip(ctx);
16415 if (bad_blocks_file)
16416 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
16418 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
16419 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16420 fatal_error(ctx, 0);
16421 #ifdef ENABLE_SWAPFS
16422 if (normalize_swapfs) {
16423 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ==
16424 ext2fs_native_flag()) {
16425 fprintf(stderr, _("%s: Filesystem byte order "
16426 "already normalized.\n"), ctx->device_name);
16427 fatal_error(ctx, 0);
16432 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
16433 fatal_error(ctx, 0);
16438 * Mark the system as valid, 'til proven otherwise
16440 ext2fs_mark_valid(fs);
16442 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
16444 com_err(ctx->program_name, retval,
16445 _("while reading bad blocks inode"));
16447 printf(_("This doesn't bode well,"
16448 " but we'll try to go on...\n"));
16451 run_result = e2fsck_run(ctx);
16452 e2fsck_clear_progbar(ctx);
16453 if (run_result == E2F_FLAG_RESTART) {
16454 printf(_("Restarting e2fsck from the beginning...\n"));
16455 retval = e2fsck_reset_context(ctx);
16457 com_err(ctx->program_name, retval,
16458 _("while resetting context"));
16459 fatal_error(ctx, 0);
16464 if (run_result & E2F_FLAG_CANCEL) {
16465 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
16466 ctx->device_name : ctx->filesystem_name);
16467 exit_value |= FSCK_CANCELED;
16469 if (run_result & E2F_FLAG_ABORT)
16470 fatal_error(ctx, _("aborted"));
16473 mtrace_print("Cleanup");
16475 if (ext2fs_test_changed(fs)) {
16476 exit_value |= FSCK_NONDESTRUCT;
16477 if (!(ctx->options & E2F_OPT_PREEN))
16478 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
16480 if (ctx->mount_flags & EXT2_MF_ISROOT) {
16481 printf(_("%s: ***** REBOOT LINUX *****\n"),
16483 exit_value |= FSCK_REBOOT;
16486 if (!ext2fs_test_valid(fs)) {
16487 printf(_("\n%s: ********** WARNING: Filesystem still has "
16488 "errors **********\n\n"), ctx->device_name);
16489 exit_value |= FSCK_UNCORRECTED;
16490 exit_value &= ~FSCK_NONDESTRUCT;
16492 if (exit_value & FSCK_CANCELED)
16493 exit_value &= ~FSCK_NONDESTRUCT;
16496 if (!(ctx->options & E2F_OPT_READONLY)) {
16497 if (ext2fs_test_valid(fs)) {
16498 if (!(sb->s_state & EXT2_VALID_FS))
16499 exit_value |= FSCK_NONDESTRUCT;
16500 sb->s_state = EXT2_VALID_FS;
16502 sb->s_state &= ~EXT2_VALID_FS;
16503 sb->s_mnt_count = 0;
16504 sb->s_lastcheck = time(NULL);
16505 ext2fs_mark_super_dirty(fs);
16509 e2fsck_write_bitmaps(ctx);
16513 free(ctx->filesystem_name);
16514 free(ctx->journal_name);
16515 e2fsck_free_context(ctx);
16517 #ifdef RESOURCE_TRACK
16518 if (ctx->options & E2F_OPT_TIME)
16519 print_resource_track(NULL, &ctx->global_rtrack);