4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * redistributed under the terms of the GNU Public License.
9 * Dictionary Abstract Data Type
10 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
11 * Free Software License:
12 * All rights are reserved by the author, with the following exceptions:
13 * Permission is granted to freely reproduce and distribute this software,
14 * possibly in exchange for a fee, provided that this copyright notice appears
15 * intact. Permission is also granted to adapt this software to produce
16 * derivative works, as long as the modified versions carry this copyright
17 * notice and additional notices stating that the work has been modified.
18 * This source code may be translated into executable form and incorporated
19 * into proprietary software; there is no requirement for such software to
20 * contain a copyright notice related to this source.
22 * linux/fs/recovery and linux/fs/revoke
23 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
25 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
27 * This file is part of the Linux kernel and is made available under
28 * the terms of the GNU General Public License, version 2, or at your
29 * option, any later version, incorporated herein by reference.
31 * Journal recovery routines for the generic filesystem journaling code;
32 * part of the ext2fs journaling system.
36 #define _GNU_SOURCE 1 /* get strnlen() */
39 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
42 #define _INLINE_ __inline__
43 #define EXT2FS_ATTR(x) __attribute__(x)
46 #define EXT2FS_ATTR(x)
50 * Procedure declarations
53 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
56 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
59 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
60 ext2_ino_t ino, char *buf);
63 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
64 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
65 int num, int gauranteed_size);
66 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
67 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
71 static void e2fsck_rehash_directories(e2fsck_t ctx);
74 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
75 const char *description);
76 static int ask(e2fsck_t ctx, const char * string, int def);
77 static void e2fsck_read_bitmaps(e2fsck_t ctx);
78 static void preenhalt(e2fsck_t ctx);
79 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
80 struct ext2_inode * inode, const char * proc);
81 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
82 struct ext2_inode * inode, const char * proc);
83 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
84 const char *name, io_manager manager);
87 static void e2fsck_clear_progbar(e2fsck_t ctx);
88 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
89 float percent, unsigned int dpynum);
93 * problem.h --- e2fsck problem error codes
96 typedef __u32 problem_t;
98 struct problem_context {
100 ext2_ino_t ino, ino2, dir;
101 struct ext2_inode *inode;
102 struct ext2_dir_entry *dirent;
104 e2_blkcnt_t blkcount;
111 * We define a set of "latch groups"; these are problems which are
112 * handled as a set. The user answers once for a particular latch
115 #define PR_LATCH_MASK 0x0ff0 /* Latch mask */
116 #define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */
117 #define PR_LATCH_BBLOCK 0x0020 /* Latch for bad block inode blocks (pass 1) */
118 #define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */
119 #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */
120 #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */
121 #define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */
122 #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
123 #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */
124 #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */
126 #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1)
129 * Latch group descriptor flags
131 #define PRL_YES 0x0001 /* Answer yes */
132 #define PRL_NO 0x0002 /* Answer no */
133 #define PRL_LATCHED 0x0004 /* The latch group is latched */
134 #define PRL_SUPPRESS 0x0008 /* Suppress all latch group questions */
136 #define PRL_VARIABLE 0x000f /* All the flags that need to be reset */
142 /* Block bitmap not in group */
143 #define PR_0_BB_NOT_GROUP 0x000001
145 /* Inode bitmap not in group */
146 #define PR_0_IB_NOT_GROUP 0x000002
148 /* Inode table not in group */
149 #define PR_0_ITABLE_NOT_GROUP 0x000003
151 /* Superblock corrupt */
152 #define PR_0_SB_CORRUPT 0x000004
154 /* Filesystem size is wrong */
155 #define PR_0_FS_SIZE_WRONG 0x000005
157 /* Fragments not supported */
158 #define PR_0_NO_FRAGMENTS 0x000006
160 /* Bad blocks_per_group */
161 #define PR_0_BLOCKS_PER_GROUP 0x000007
163 /* Bad first_data_block */
164 #define PR_0_FIRST_DATA_BLOCK 0x000008
166 /* Adding UUID to filesystem */
167 #define PR_0_ADD_UUID 0x000009
170 #define PR_0_RELOCATE_HINT 0x00000A
172 /* Miscellaneous superblock corruption */
173 #define PR_0_MISC_CORRUPT_SUPER 0x00000B
175 /* Error determing physical device size of filesystem */
176 #define PR_0_GETSIZE_ERROR 0x00000C
178 /* Inode count in the superblock incorrect */
179 #define PR_0_INODE_COUNT_WRONG 0x00000D
181 /* The Hurd does not support the filetype feature */
182 #define PR_0_HURD_CLEAR_FILETYPE 0x00000E
184 /* Journal inode is invalid */
185 #define PR_0_JOURNAL_BAD_INODE 0x00000F
187 /* The external journal has multiple filesystems (which we can't handle yet) */
188 #define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010
190 /* Can't find external journal */
191 #define PR_0_CANT_FIND_JOURNAL 0x000011
193 /* External journal has bad superblock */
194 #define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012
196 /* Superblock has a bad journal UUID */
197 #define PR_0_JOURNAL_BAD_UUID 0x000013
199 /* Journal has an unknown superblock type */
200 #define PR_0_JOURNAL_UNSUPP_SUPER 0x000014
202 /* Journal superblock is corrupt */
203 #define PR_0_JOURNAL_BAD_SUPER 0x000015
205 /* Journal superblock is corrupt */
206 #define PR_0_JOURNAL_HAS_JOURNAL 0x000016
208 /* Superblock has recovery flag set but no journal */
209 #define PR_0_JOURNAL_RECOVER_SET 0x000017
211 /* Journal has data, but recovery flag is clear */
212 #define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018
214 /* Ask if we should clear the journal */
215 #define PR_0_JOURNAL_RESET_JOURNAL 0x000019
217 /* Filesystem revision is 0, but feature flags are set */
218 #define PR_0_FS_REV_LEVEL 0x00001A
220 /* Clearing orphan inode */
221 #define PR_0_ORPHAN_CLEAR_INODE 0x000020
223 /* Illegal block found in orphaned inode */
224 #define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021
226 /* Already cleared block found in orphaned inode */
227 #define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
229 /* Illegal orphan inode in superblock */
230 #define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023
232 /* Illegal inode in orphaned inode list */
233 #define PR_0_ORPHAN_ILLEGAL_INODE 0x000024
235 /* Journal has unsupported read-only feature - abort */
236 #define PR_0_JOURNAL_UNSUPP_ROCOMPAT 0x000025
238 /* Journal has unsupported incompatible feature - abort */
239 #define PR_0_JOURNAL_UNSUPP_INCOMPAT 0x000026
241 /* Journal has unsupported version number */
242 #define PR_0_JOURNAL_UNSUPP_VERSION 0x000027
244 /* Moving journal to hidden file */
245 #define PR_0_MOVE_JOURNAL 0x000028
247 /* Error moving journal */
248 #define PR_0_ERR_MOVE_JOURNAL 0x000029
250 /* Clearing V2 journal superblock */
251 #define PR_0_CLEAR_V2_JOURNAL 0x00002A
253 /* Run journal anyway */
254 #define PR_0_JOURNAL_RUN 0x00002B
256 /* Run journal anyway by default */
257 #define PR_0_JOURNAL_RUN_DEFAULT 0x00002C
259 /* Backup journal inode blocks */
260 #define PR_0_BACKUP_JNL 0x00002D
262 /* Reserved blocks w/o resize_inode */
263 #define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E
265 /* Resize_inode not enabled, but resize inode is non-zero */
266 #define PR_0_CLEAR_RESIZE_INODE 0x00002F
268 /* Resize inode invalid */
269 #define PR_0_RESIZE_INODE_INVALID 0x000030
275 /* Pass 1: Checking inodes, blocks, and sizes */
276 #define PR_1_PASS_HEADER 0x010000
278 /* Root directory is not an inode */
279 #define PR_1_ROOT_NO_DIR 0x010001
281 /* Root directory has dtime set */
282 #define PR_1_ROOT_DTIME 0x010002
284 /* Reserved inode has bad mode */
285 #define PR_1_RESERVED_BAD_MODE 0x010003
287 /* Deleted inode has zero dtime */
288 #define PR_1_ZERO_DTIME 0x010004
290 /* Inode in use, but dtime set */
291 #define PR_1_SET_DTIME 0x010005
293 /* Zero-length directory */
294 #define PR_1_ZERO_LENGTH_DIR 0x010006
296 /* Block bitmap conflicts with some other fs block */
297 #define PR_1_BB_CONFLICT 0x010007
299 /* Inode bitmap conflicts with some other fs block */
300 #define PR_1_IB_CONFLICT 0x010008
302 /* Inode table conflicts with some other fs block */
303 #define PR_1_ITABLE_CONFLICT 0x010009
305 /* Block bitmap is on a bad block */
306 #define PR_1_BB_BAD_BLOCK 0x01000A
308 /* Inode bitmap is on a bad block */
309 #define PR_1_IB_BAD_BLOCK 0x01000B
311 /* Inode has incorrect i_size */
312 #define PR_1_BAD_I_SIZE 0x01000C
314 /* Inode has incorrect i_blocks */
315 #define PR_1_BAD_I_BLOCKS 0x01000D
317 /* Illegal block number in inode */
318 #define PR_1_ILLEGAL_BLOCK_NUM 0x01000E
320 /* Block number overlaps fs metadata */
321 #define PR_1_BLOCK_OVERLAPS_METADATA 0x01000F
323 /* Inode has illegal blocks (latch question) */
324 #define PR_1_INODE_BLOCK_LATCH 0x010010
326 /* Too many bad blocks in inode */
327 #define PR_1_TOO_MANY_BAD_BLOCKS 0x010011
329 /* Illegal block number in bad block inode */
330 #define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012
332 /* Bad block inode has illegal blocks (latch question) */
333 #define PR_1_INODE_BBLOCK_LATCH 0x010013
335 /* Duplicate or bad blocks in use! */
336 #define PR_1_DUP_BLOCKS_PREENSTOP 0x010014
338 /* Bad block used as bad block indirect block */
339 #define PR_1_BBINODE_BAD_METABLOCK 0x010015
341 /* Inconsistency can't be fixed prompt */
342 #define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
344 /* Bad primary block */
345 #define PR_1_BAD_PRIMARY_BLOCK 0x010017
347 /* Bad primary block prompt */
348 #define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018
350 /* Bad primary superblock */
351 #define PR_1_BAD_PRIMARY_SUPERBLOCK 0x010019
353 /* Bad primary block group descriptors */
354 #define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A
356 /* Bad superblock in group */
357 #define PR_1_BAD_SUPERBLOCK 0x01001B
359 /* Bad block group descriptors in group */
360 #define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C
362 /* Block claimed for no reason */
363 #define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D
365 /* Error allocating blocks for relocating metadata */
366 #define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E
368 /* Error allocating block buffer during relocation process */
369 #define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F
371 /* Relocating metadata group information from X to Y */
372 #define PR_1_RELOC_FROM_TO 0x010020
374 /* Relocating metatdata group information to X */
375 #define PR_1_RELOC_TO 0x010021
377 /* Block read error during relocation process */
378 #define PR_1_RELOC_READ_ERR 0x010022
380 /* Block write error during relocation process */
381 #define PR_1_RELOC_WRITE_ERR 0x010023
383 /* Error allocating inode bitmap */
384 #define PR_1_ALLOCATE_IBITMAP_ERROR 0x010024
386 /* Error allocating block bitmap */
387 #define PR_1_ALLOCATE_BBITMAP_ERROR 0x010025
389 /* Error allocating icount structure */
390 #define PR_1_ALLOCATE_ICOUNT 0x010026
392 /* Error allocating dbcount */
393 #define PR_1_ALLOCATE_DBCOUNT 0x010027
395 /* Error while scanning inodes */
396 #define PR_1_ISCAN_ERROR 0x010028
398 /* Error while iterating over blocks */
399 #define PR_1_BLOCK_ITERATE 0x010029
401 /* Error while storing inode count information */
402 #define PR_1_ICOUNT_STORE 0x01002A
404 /* Error while storing directory block information */
405 #define PR_1_ADD_DBLOCK 0x01002B
407 /* Error while reading inode (for clearing) */
408 #define PR_1_READ_INODE 0x01002C
410 /* Suppress messages prompt */
411 #define PR_1_SUPPRESS_MESSAGES 0x01002D
413 /* Imagic flag set on an inode when filesystem doesn't support it */
414 #define PR_1_SET_IMAGIC 0x01002F
416 /* Immutable flag set on a device or socket inode */
417 #define PR_1_SET_IMMUTABLE 0x010030
419 /* Compression flag set on a non-compressed filesystem */
420 #define PR_1_COMPR_SET 0x010031
422 /* Non-zero size on on device, fifo or socket inode */
423 #define PR_1_SET_NONZSIZE 0x010032
425 /* Filesystem revision is 0, but feature flags are set */
426 #define PR_1_FS_REV_LEVEL 0x010033
428 /* Journal inode not in use, needs clearing */
429 #define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034
431 /* Journal inode has wrong mode */
432 #define PR_1_JOURNAL_BAD_MODE 0x010035
434 /* Inode that was part of orphan linked list */
435 #define PR_1_LOW_DTIME 0x010036
437 /* Latch question which asks how to deal with low dtime inodes */
438 #define PR_1_ORPHAN_LIST_REFUGEES 0x010037
440 /* Error allocating refcount structure */
441 #define PR_1_ALLOCATE_REFCOUNT 0x010038
443 /* Error reading Extended Attribute block */
444 #define PR_1_READ_EA_BLOCK 0x010039
446 /* Invalid Extended Attribute block */
447 #define PR_1_BAD_EA_BLOCK 0x01003A
449 /* Error reading Extended Attribute block while fixing refcount -- abort */
450 #define PR_1_EXTATTR_READ_ABORT 0x01003B
452 /* Extended attribute reference count incorrect */
453 #define PR_1_EXTATTR_REFCOUNT 0x01003C
455 /* Error writing Extended Attribute block while fixing refcount */
456 #define PR_1_EXTATTR_WRITE 0x01003D
458 /* Multiple EA blocks not supported */
459 #define PR_1_EA_MULTI_BLOCK 0x01003E
461 /* Error allocating EA region allocation structure */
462 #define PR_1_EA_ALLOC_REGION 0x01003F
464 /* Error EA allocation collision */
465 #define PR_1_EA_ALLOC_COLLISION 0x010040
467 /* Bad extended attribute name */
468 #define PR_1_EA_BAD_NAME 0x010041
470 /* Bad extended attribute value */
471 #define PR_1_EA_BAD_VALUE 0x010042
473 /* Inode too big (latch question) */
474 #define PR_1_INODE_TOOBIG 0x010043
476 /* Directory too big */
477 #define PR_1_TOOBIG_DIR 0x010044
479 /* Regular file too big */
480 #define PR_1_TOOBIG_REG 0x010045
482 /* Symlink too big */
483 #define PR_1_TOOBIG_SYMLINK 0x010046
485 /* INDEX_FL flag set on a non-HTREE filesystem */
486 #define PR_1_HTREE_SET 0x010047
488 /* INDEX_FL flag set on a non-directory */
489 #define PR_1_HTREE_NODIR 0x010048
491 /* Invalid root node in HTREE directory */
492 #define PR_1_HTREE_BADROOT 0x010049
494 /* Unsupported hash version in HTREE directory */
495 #define PR_1_HTREE_HASHV 0x01004A
497 /* Incompatible flag in HTREE root node */
498 #define PR_1_HTREE_INCOMPAT 0x01004B
501 #define PR_1_HTREE_DEPTH 0x01004C
503 /* Bad block has indirect block that conflicts with filesystem block */
504 #define PR_1_BB_FS_BLOCK 0x01004D
506 /* Resize inode failed */
507 #define PR_1_RESIZE_INODE_CREATE 0x01004E
509 /* inode->i_size is too long */
510 #define PR_1_EXTRA_ISIZE 0x01004F
512 /* attribute name is too long */
513 #define PR_1_ATTR_NAME_LEN 0x010050
515 /* wrong EA value offset */
516 #define PR_1_ATTR_VALUE_OFFSET 0x010051
518 /* wrong EA blocknumber */
519 #define PR_1_ATTR_VALUE_BLOCK 0x010052
521 /* wrong EA value size */
522 #define PR_1_ATTR_VALUE_SIZE 0x010053
524 /* wrong EA hash value */
525 #define PR_1_ATTR_HASH 0x010054
531 /* Pass 1B: Rescan for duplicate/bad blocks */
532 #define PR_1B_PASS_HEADER 0x011000
534 /* Duplicate/bad block(s) header */
535 #define PR_1B_DUP_BLOCK_HEADER 0x011001
537 /* Duplicate/bad block(s) in inode */
538 #define PR_1B_DUP_BLOCK 0x011002
540 /* Duplicate/bad block(s) end */
541 #define PR_1B_DUP_BLOCK_END 0x011003
543 /* Error while scanning inodes */
544 #define PR_1B_ISCAN_ERROR 0x011004
546 /* Error allocating inode bitmap */
547 #define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005
549 /* Error while iterating over blocks */
550 #define PR_1B_BLOCK_ITERATE 0x0110006
552 /* Error adjusting EA refcount */
553 #define PR_1B_ADJ_EA_REFCOUNT 0x0110007
556 /* Pass 1C: Scan directories for inodes with dup blocks. */
557 #define PR_1C_PASS_HEADER 0x012000
560 /* Pass 1D: Reconciling duplicate blocks */
561 #define PR_1D_PASS_HEADER 0x013000
563 /* File has duplicate blocks */
564 #define PR_1D_DUP_FILE 0x013001
566 /* List of files sharing duplicate blocks */
567 #define PR_1D_DUP_FILE_LIST 0x013002
569 /* File sharing blocks with filesystem metadata */
570 #define PR_1D_SHARE_METADATA 0x013003
572 /* Report of how many duplicate/bad inodes */
573 #define PR_1D_NUM_DUP_INODES 0x013004
575 /* Duplicated blocks already reassigned or cloned. */
576 #define PR_1D_DUP_BLOCKS_DEALT 0x013005
578 /* Clone duplicate/bad blocks? */
579 #define PR_1D_CLONE_QUESTION 0x013006
582 #define PR_1D_DELETE_QUESTION 0x013007
584 /* Couldn't clone file (error) */
585 #define PR_1D_CLONE_ERROR 0x013008
591 /* Pass 2: Checking directory structure */
592 #define PR_2_PASS_HEADER 0x020000
594 /* Bad inode number for '.' */
595 #define PR_2_BAD_INODE_DOT 0x020001
597 /* Directory entry has bad inode number */
598 #define PR_2_BAD_INO 0x020002
600 /* Directory entry has deleted or unused inode */
601 #define PR_2_UNUSED_INODE 0x020003
603 /* Directry entry is link to '.' */
604 #define PR_2_LINK_DOT 0x020004
606 /* Directory entry points to inode now located in a bad block */
607 #define PR_2_BB_INODE 0x020005
609 /* Directory entry contains a link to a directory */
610 #define PR_2_LINK_DIR 0x020006
612 /* Directory entry contains a link to the root directry */
613 #define PR_2_LINK_ROOT 0x020007
615 /* Directory entry has illegal characters in its name */
616 #define PR_2_BAD_NAME 0x020008
618 /* Missing '.' in directory inode */
619 #define PR_2_MISSING_DOT 0x020009
621 /* Missing '..' in directory inode */
622 #define PR_2_MISSING_DOT_DOT 0x02000A
624 /* First entry in directory inode doesn't contain '.' */
625 #define PR_2_1ST_NOT_DOT 0x02000B
627 /* Second entry in directory inode doesn't contain '..' */
628 #define PR_2_2ND_NOT_DOT_DOT 0x02000C
630 /* i_faddr should be zero */
631 #define PR_2_FADDR_ZERO 0x02000D
633 /* i_file_acl should be zero */
634 #define PR_2_FILE_ACL_ZERO 0x02000E
636 /* i_dir_acl should be zero */
637 #define PR_2_DIR_ACL_ZERO 0x02000F
639 /* i_frag should be zero */
640 #define PR_2_FRAG_ZERO 0x020010
642 /* i_fsize should be zero */
643 #define PR_2_FSIZE_ZERO 0x020011
645 /* inode has bad mode */
646 #define PR_2_BAD_MODE 0x020012
648 /* directory corrupted */
649 #define PR_2_DIR_CORRUPTED 0x020013
651 /* filename too long */
652 #define PR_2_FILENAME_LONG 0x020014
654 /* Directory inode has a missing block (hole) */
655 #define PR_2_DIRECTORY_HOLE 0x020015
657 /* '.' is not NULL terminated */
658 #define PR_2_DOT_NULL_TERM 0x020016
660 /* '..' is not NULL terminated */
661 #define PR_2_DOT_DOT_NULL_TERM 0x020017
663 /* Illegal character device in inode */
664 #define PR_2_BAD_CHAR_DEV 0x020018
666 /* Illegal block device in inode */
667 #define PR_2_BAD_BLOCK_DEV 0x020019
669 /* Duplicate '.' entry */
670 #define PR_2_DUP_DOT 0x02001A
672 /* Duplicate '..' entry */
673 #define PR_2_DUP_DOT_DOT 0x02001B
675 /* Internal error: couldn't find dir_info */
676 #define PR_2_NO_DIRINFO 0x02001C
678 /* Final rec_len is wrong */
679 #define PR_2_FINAL_RECLEN 0x02001D
681 /* Error allocating icount structure */
682 #define PR_2_ALLOCATE_ICOUNT 0x02001E
684 /* Error iterating over directory blocks */
685 #define PR_2_DBLIST_ITERATE 0x02001F
687 /* Error reading directory block */
688 #define PR_2_READ_DIRBLOCK 0x020020
690 /* Error writing directory block */
691 #define PR_2_WRITE_DIRBLOCK 0x020021
693 /* Error allocating new directory block */
694 #define PR_2_ALLOC_DIRBOCK 0x020022
696 /* Error deallocating inode */
697 #define PR_2_DEALLOC_INODE 0x020023
699 /* Directory entry for '.' is big. Split? */
700 #define PR_2_SPLIT_DOT 0x020024
703 #define PR_2_BAD_FIFO 0x020025
706 #define PR_2_BAD_SOCKET 0x020026
708 /* Directory filetype not set */
709 #define PR_2_SET_FILETYPE 0x020027
711 /* Directory filetype incorrect */
712 #define PR_2_BAD_FILETYPE 0x020028
714 /* Directory filetype set when it shouldn't be */
715 #define PR_2_CLEAR_FILETYPE 0x020029
717 /* Directory filename can't be zero-length */
718 #define PR_2_NULL_NAME 0x020030
720 /* Invalid symlink */
721 #define PR_2_INVALID_SYMLINK 0x020031
723 /* i_file_acl (extended attribute) is bad */
724 #define PR_2_FILE_ACL_BAD 0x020032
726 /* Filesystem contains large files, but has no such flag in sb */
727 #define PR_2_FEATURE_LARGE_FILES 0x020033
729 /* Node in HTREE directory not referenced */
730 #define PR_2_HTREE_NOTREF 0x020034
732 /* Node in HTREE directory referenced twice */
733 #define PR_2_HTREE_DUPREF 0x020035
735 /* Node in HTREE directory has bad min hash */
736 #define PR_2_HTREE_MIN_HASH 0x020036
738 /* Node in HTREE directory has bad max hash */
739 #define PR_2_HTREE_MAX_HASH 0x020037
741 /* Clear invalid HTREE directory */
742 #define PR_2_HTREE_CLEAR 0x020038
744 /* Clear the htree flag forcibly */
745 /* #define PR_2_HTREE_FCLR 0x020039 */
747 /* Bad block in htree interior node */
748 #define PR_2_HTREE_BADBLK 0x02003A
750 /* Error adjusting EA refcount */
751 #define PR_2_ADJ_EA_REFCOUNT 0x02003B
753 /* Invalid HTREE root node */
754 #define PR_2_HTREE_BAD_ROOT 0x02003C
756 /* Invalid HTREE limit */
757 #define PR_2_HTREE_BAD_LIMIT 0x02003D
759 /* Invalid HTREE count */
760 #define PR_2_HTREE_BAD_COUNT 0x02003E
762 /* HTREE interior node has out-of-order hashes in table */
763 #define PR_2_HTREE_HASH_ORDER 0x02003F
765 /* Node in HTREE directory has bad depth */
766 #define PR_2_HTREE_BAD_DEPTH 0x020040
768 /* Duplicate directory entry found */
769 #define PR_2_DUPLICATE_DIRENT 0x020041
771 /* Non-unique filename found */
772 #define PR_2_NON_UNIQUE_FILE 0x020042
774 /* Duplicate directory entry found */
775 #define PR_2_REPORT_DUP_DIRENT 0x020043
781 /* Pass 3: Checking directory connectivity */
782 #define PR_3_PASS_HEADER 0x030000
784 /* Root inode not allocated */
785 #define PR_3_NO_ROOT_INODE 0x030001
787 /* No room in lost+found */
788 #define PR_3_EXPAND_LF_DIR 0x030002
790 /* Unconnected directory inode */
791 #define PR_3_UNCONNECTED_DIR 0x030003
793 /* /lost+found not found */
794 #define PR_3_NO_LF_DIR 0x030004
796 /* .. entry is incorrect */
797 #define PR_3_BAD_DOT_DOT 0x030005
799 /* Bad or non-existent /lost+found. Cannot reconnect */
800 #define PR_3_NO_LPF 0x030006
802 /* Could not expand /lost+found */
803 #define PR_3_CANT_EXPAND_LPF 0x030007
805 /* Could not reconnect inode */
806 #define PR_3_CANT_RECONNECT 0x030008
808 /* Error while trying to find /lost+found */
809 #define PR_3_ERR_FIND_LPF 0x030009
811 /* Error in ext2fs_new_block while creating /lost+found */
812 #define PR_3_ERR_LPF_NEW_BLOCK 0x03000A
814 /* Error in ext2fs_new_inode while creating /lost+found */
815 #define PR_3_ERR_LPF_NEW_INODE 0x03000B
817 /* Error in ext2fs_new_dir_block while creating /lost+found */
818 #define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C
820 /* Error while writing directory block for /lost+found */
821 #define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D
823 /* Error while adjusting inode count */
824 #define PR_3_ADJUST_INODE 0x03000E
826 /* Couldn't fix parent directory -- error */
827 #define PR_3_FIX_PARENT_ERR 0x03000F
829 /* Couldn't fix parent directory -- couldn't find it */
830 #define PR_3_FIX_PARENT_NOFIND 0x030010
832 /* Error allocating inode bitmap */
833 #define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011
835 /* Error creating root directory */
836 #define PR_3_CREATE_ROOT_ERROR 0x030012
838 /* Error creating lost and found directory */
839 #define PR_3_CREATE_LPF_ERROR 0x030013
841 /* Root inode is not directory; aborting */
842 #define PR_3_ROOT_NOT_DIR_ABORT 0x030014
844 /* Cannot proceed without a root inode. */
845 #define PR_3_NO_ROOT_INODE_ABORT 0x030015
847 /* Internal error: couldn't find dir_info */
848 #define PR_3_NO_DIRINFO 0x030016
850 /* Lost+found is not a directory */
851 #define PR_3_LPF_NOTDIR 0x030017
854 * Pass 3a --- rehashing diretories
856 /* Pass 3a: Reindexing directories */
857 #define PR_3A_PASS_HEADER 0x031000
859 /* Error iterating over directories */
860 #define PR_3A_OPTIMIZE_ITER 0x031001
862 /* Error rehash directory */
863 #define PR_3A_OPTIMIZE_DIR_ERR 0x031002
865 /* Rehashing dir header */
866 #define PR_3A_OPTIMIZE_DIR_HEADER 0x031003
868 /* Rehashing directory %d */
869 #define PR_3A_OPTIMIZE_DIR 0x031004
871 /* Rehashing dir end */
872 #define PR_3A_OPTIMIZE_DIR_END 0x031005
878 /* Pass 4: Checking reference counts */
879 #define PR_4_PASS_HEADER 0x040000
881 /* Unattached zero-length inode */
882 #define PR_4_ZERO_LEN_INODE 0x040001
884 /* Unattached inode */
885 #define PR_4_UNATTACHED_INODE 0x040002
887 /* Inode ref count wrong */
888 #define PR_4_BAD_REF_COUNT 0x040003
890 /* Inconsistent inode count information cached */
891 #define PR_4_INCONSISTENT_COUNT 0x040004
897 /* Pass 5: Checking group summary information */
898 #define PR_5_PASS_HEADER 0x050000
900 /* Padding at end of inode bitmap is not set. */
901 #define PR_5_INODE_BMAP_PADDING 0x050001
903 /* Padding at end of block bitmap is not set. */
904 #define PR_5_BLOCK_BMAP_PADDING 0x050002
906 /* Block bitmap differences header */
907 #define PR_5_BLOCK_BITMAP_HEADER 0x050003
909 /* Block not used, but marked in bitmap */
910 #define PR_5_BLOCK_UNUSED 0x050004
912 /* Block used, but not marked used in bitmap */
913 #define PR_5_BLOCK_USED 0x050005
915 /* Block bitmap differences end */
916 #define PR_5_BLOCK_BITMAP_END 0x050006
918 /* Inode bitmap differences header */
919 #define PR_5_INODE_BITMAP_HEADER 0x050007
921 /* Inode not used, but marked in bitmap */
922 #define PR_5_INODE_UNUSED 0x050008
924 /* Inode used, but not marked used in bitmap */
925 #define PR_5_INODE_USED 0x050009
927 /* Inode bitmap differences end */
928 #define PR_5_INODE_BITMAP_END 0x05000A
930 /* Free inodes count for group wrong */
931 #define PR_5_FREE_INODE_COUNT_GROUP 0x05000B
933 /* Directories count for group wrong */
934 #define PR_5_FREE_DIR_COUNT_GROUP 0x05000C
936 /* Free inodes count wrong */
937 #define PR_5_FREE_INODE_COUNT 0x05000D
939 /* Free blocks count for group wrong */
940 #define PR_5_FREE_BLOCK_COUNT_GROUP 0x05000E
942 /* Free blocks count wrong */
943 #define PR_5_FREE_BLOCK_COUNT 0x05000F
945 /* Programming error: bitmap endpoints don't match */
946 #define PR_5_BMAP_ENDPOINTS 0x050010
948 /* Internal error: fudging end of bitmap */
949 #define PR_5_FUDGE_BITMAP_ERROR 0x050011
951 /* Error copying in replacement inode bitmap */
952 #define PR_5_COPY_IBITMAP_ERROR 0x050012
954 /* Error copying in replacement block bitmap */
955 #define PR_5_COPY_BBITMAP_ERROR 0x050013
957 /* Block range not used, but marked in bitmap */
958 #define PR_5_BLOCK_RANGE_UNUSED 0x050014
960 /* Block range used, but not marked used in bitmap */
961 #define PR_5_BLOCK_RANGE_USED 0x050015
963 /* Inode range not used, but marked in bitmap */
964 #define PR_5_INODE_RANGE_UNUSED 0x050016
966 /* Inode rangeused, but not marked used in bitmap */
967 #define PR_5_INODE_RANGE_USED 0x050017
970 * Function declarations
972 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
973 static int end_problem_latch(e2fsck_t ctx, int mask);
974 static int set_latch_flags(int mask, int setflags, int clearflags);
975 static void clear_problem_context(struct problem_context *ctx);
978 * Dictionary Abstract Data Type
979 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
981 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
989 * Blurb for inclusion into C++ translation units
992 typedef unsigned long dictcount_t;
993 #define DICTCOUNT_T_MAX ULONG_MAX
996 * The dictionary is implemented as a red-black tree
999 typedef enum { dnode_red, dnode_black } dnode_color_t;
1001 typedef struct dnode_t {
1002 struct dnode_t *dict_left;
1003 struct dnode_t *dict_right;
1004 struct dnode_t *dict_parent;
1005 dnode_color_t dict_color;
1006 const void *dict_key;
1010 typedef int (*dict_comp_t)(const void *, const void *);
1011 typedef void (*dnode_free_t)(dnode_t *);
1013 typedef struct dict_t {
1014 dnode_t dict_nilnode;
1015 dictcount_t dict_nodecount;
1016 dictcount_t dict_maxcount;
1017 dict_comp_t dict_compare;
1018 dnode_free_t dict_freenode;
1022 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
1024 typedef struct dict_load_t {
1025 dict_t *dict_dictptr;
1026 dnode_t dict_nilnode;
1029 #define dict_count(D) ((D)->dict_nodecount)
1030 #define dnode_get(N) ((N)->dict_data)
1031 #define dnode_getkey(N) ((N)->dict_key)
1036 * Compatibility header file for e2fsck which should be included
1037 * instead of linux/jfs.h
1039 * Copyright (C) 2000 Stephen C. Tweedie
1043 * Pull in the definition of the e2fsck context structure
1046 struct buffer_head {
1059 #define K_DEV_JOURNAL 2
1061 #define lock_buffer(bh) do {} while(0)
1062 #define unlock_buffer(bh) do {} while(0)
1063 #define buffer_req(bh) 1
1064 #define do_readahead(journal, start) do {} while(0)
1066 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
1072 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
1075 * We use the standard libext2fs portability tricks for inline
1079 static _INLINE_ kmem_cache_t * do_cache_create(int len)
1081 kmem_cache_t *new_cache;
1083 new_cache = malloc(sizeof(*new_cache));
1085 new_cache->object_length = len;
1089 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
1095 * badblocks.c --- replace/append bad blocks to the bad block inode
1098 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
1102 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
1104 printf(_("Bad block %u out of range; ignored.\n"), blk);
1108 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
1109 int replace_bad_blocks)
1111 ext2_filsys fs = ctx->fs;
1113 badblocks_list bb_list = 0;
1117 e2fsck_read_bitmaps(ctx);
1120 * Make sure the bad block inode is sane. If there are any
1121 * illegal blocks, clear them.
1123 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
1124 check_bb_inode_blocks, 0);
1126 com_err("ext2fs_block_iterate", retval,
1127 _("while sanity checking the bad blocks inode"));
1132 * If we're appending to the bad blocks inode, read in the
1133 * current bad blocks.
1135 if (!replace_bad_blocks) {
1136 retval = ext2fs_read_bb_inode(fs, &bb_list);
1138 com_err("ext2fs_read_bb_inode", retval,
1139 _("while reading the bad blocks inode"));
1145 * Now read in the bad blocks from the file; if
1146 * bad_blocks_file is null, then try to run the badblocks
1149 if (bad_blocks_file) {
1150 f = fopen(bad_blocks_file, "r");
1152 com_err("read_bad_blocks_file", errno,
1153 _("while trying to open %s"), bad_blocks_file);
1157 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
1158 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
1159 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
1160 fs->device_name, fs->super->s_blocks_count);
1161 f = popen(buf, "r");
1163 com_err("read_bad_blocks_file", errno,
1164 _("while trying popen '%s'"), buf);
1168 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
1169 if (bad_blocks_file)
1174 com_err("ext2fs_read_bb_FILE", retval,
1175 _("while reading in list of bad blocks from file"));
1180 * Finally, update the bad blocks from the bad_block_map
1182 retval = ext2fs_update_bb_inode(fs, bb_list);
1184 com_err("ext2fs_update_bb_inode", retval,
1185 _("while updating bad block inode"));
1189 ext2fs_badblocks_list_free(bb_list);
1193 ctx->flags |= E2F_FLAG_ABORT;
1198 static int check_bb_inode_blocks(ext2_filsys fs,
1200 int blockcnt FSCK_ATTR((unused)),
1201 void *priv_data FSCK_ATTR((unused)))
1207 * If the block number is outrageous, clear it and ignore it.
1209 if (*block_nr >= fs->super->s_blocks_count ||
1210 *block_nr < fs->super->s_first_data_block) {
1211 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
1213 return BLOCK_CHANGED;
1220 * Dictionary Abstract Data Type
1225 * These macros provide short convenient names for structure members,
1226 * which are embellished with dict_ prefixes so that they are
1227 * properly confined to the documented namespace. It's legal for a
1228 * program which uses dict to define, for instance, a macro called ``parent''.
1229 * Such a macro would interfere with the dnode_t struct definition.
1230 * In general, highly portable and reusable C modules which expose their
1231 * structures need to confine structure member names to well-defined spaces.
1232 * The resulting identifiers aren't necessarily convenient to use, nor
1233 * readable, in the implementation, however!
1236 #define left dict_left
1237 #define right dict_right
1238 #define parent dict_parent
1239 #define color dict_color
1240 #define key dict_key
1241 #define data dict_data
1243 #define nilnode dict_nilnode
1244 #define maxcount dict_maxcount
1245 #define compare dict_compare
1246 #define dupes dict_dupes
1248 #define dict_root(D) ((D)->nilnode.left)
1249 #define dict_nil(D) (&(D)->nilnode)
1250 #define DICT_DEPTH_MAX 64
1252 static void dnode_free(dnode_t *node);
1255 * Perform a ``left rotation'' adjustment on the tree. The given node P and
1256 * its right child C are rearranged so that the P instead becomes the left
1257 * child of C. The left subtree of C is inherited as the new right subtree
1258 * for P. The ordering of the keys within the tree is thus preserved.
1261 static void rotate_left(dnode_t *upper)
1263 dnode_t *lower, *lowleft, *upparent;
1265 lower = upper->right;
1266 upper->right = lowleft = lower->left;
1267 lowleft->parent = upper;
1269 lower->parent = upparent = upper->parent;
1271 /* don't need to check for root node here because root->parent is
1272 the sentinel nil node, and root->parent->left points back to root */
1274 if (upper == upparent->left) {
1275 upparent->left = lower;
1277 assert (upper == upparent->right);
1278 upparent->right = lower;
1281 lower->left = upper;
1282 upper->parent = lower;
1286 * This operation is the ``mirror'' image of rotate_left. It is
1287 * the same procedure, but with left and right interchanged.
1290 static void rotate_right(dnode_t *upper)
1292 dnode_t *lower, *lowright, *upparent;
1294 lower = upper->left;
1295 upper->left = lowright = lower->right;
1296 lowright->parent = upper;
1298 lower->parent = upparent = upper->parent;
1300 if (upper == upparent->right) {
1301 upparent->right = lower;
1303 assert (upper == upparent->left);
1304 upparent->left = lower;
1307 lower->right = upper;
1308 upper->parent = lower;
1312 * Do a postorder traversal of the tree rooted at the specified
1313 * node and free everything under it. Used by dict_free().
1316 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
1320 free_nodes(dict, node->left, nil);
1321 free_nodes(dict, node->right, nil);
1322 dict->dict_freenode(node);
1326 * Verify that the tree contains the given node. This is done by
1327 * traversing all of the nodes and comparing their pointers to the
1328 * given pointer. Returns 1 if the node is found, otherwise
1329 * returns zero. It is intended for debugging purposes.
1332 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
1336 || verify_dict_has_node(nil, root->left, node)
1337 || verify_dict_has_node(nil, root->right, node);
1344 * Select a different set of node allocator routines.
1347 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
1349 assert (dict_count(dict) == 0);
1350 dict->dict_freenode = fr;
1354 * Free all the nodes in the dictionary by using the dictionary's
1355 * installed free routine. The dictionary is emptied.
1358 static void dict_free_nodes(dict_t *dict)
1360 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
1361 free_nodes(dict, root, nil);
1362 dict->dict_nodecount = 0;
1363 dict->nilnode.left = &dict->nilnode;
1364 dict->nilnode.right = &dict->nilnode;
1368 * Initialize a user-supplied dictionary object.
1371 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
1373 dict->compare = comp;
1374 dict->dict_freenode = dnode_free;
1375 dict->dict_nodecount = 0;
1376 dict->maxcount = maxcount;
1377 dict->nilnode.left = &dict->nilnode;
1378 dict->nilnode.right = &dict->nilnode;
1379 dict->nilnode.parent = &dict->nilnode;
1380 dict->nilnode.color = dnode_black;
1386 * Locate a node in the dictionary having the given key.
1387 * If the node is not found, a null a pointer is returned (rather than
1388 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
1389 * located node is returned.
1392 static dnode_t *dict_lookup(dict_t *dict, const void *key)
1394 dnode_t *root = dict_root(dict);
1395 dnode_t *nil = dict_nil(dict);
1399 /* simple binary search adapted for trees that contain duplicate keys */
1401 while (root != nil) {
1402 result = dict->compare(key, root->key);
1405 else if (result > 0)
1408 if (!dict->dupes) { /* no duplicates, return match */
1410 } else { /* could be dupes, find leftmost one */
1414 while (root != nil && dict->compare(key, root->key))
1416 } while (root != nil);
1426 * Insert a node into the dictionary. The node should have been
1427 * initialized with a data field. All other fields are ignored.
1428 * The behavior is undefined if the user attempts to insert into
1429 * a dictionary that is already full (for which the dict_isfull()
1430 * function returns true).
1433 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
1435 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
1436 dnode_t *parent = nil, *uncle, *grandpa;
1441 /* basic binary tree insert */
1443 while (where != nil) {
1445 result = dict->compare(key, where->key);
1446 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
1447 assert (dict->dupes || result != 0);
1449 where = where->left;
1451 where = where->right;
1454 assert (where == nil);
1457 parent->left = node;
1459 parent->right = node;
1461 node->parent = parent;
1465 dict->dict_nodecount++;
1467 /* red black adjustments */
1469 node->color = dnode_red;
1471 while (parent->color == dnode_red) {
1472 grandpa = parent->parent;
1473 if (parent == grandpa->left) {
1474 uncle = grandpa->right;
1475 if (uncle->color == dnode_red) { /* red parent, red uncle */
1476 parent->color = dnode_black;
1477 uncle->color = dnode_black;
1478 grandpa->color = dnode_red;
1480 parent = grandpa->parent;
1481 } else { /* red parent, black uncle */
1482 if (node == parent->right) {
1483 rotate_left(parent);
1485 assert (grandpa == parent->parent);
1486 /* rotation between parent and child preserves grandpa */
1488 parent->color = dnode_black;
1489 grandpa->color = dnode_red;
1490 rotate_right(grandpa);
1493 } else { /* symmetric cases: parent == parent->parent->right */
1494 uncle = grandpa->left;
1495 if (uncle->color == dnode_red) {
1496 parent->color = dnode_black;
1497 uncle->color = dnode_black;
1498 grandpa->color = dnode_red;
1500 parent = grandpa->parent;
1502 if (node == parent->left) {
1503 rotate_right(parent);
1505 assert (grandpa == parent->parent);
1507 parent->color = dnode_black;
1508 grandpa->color = dnode_red;
1509 rotate_left(grandpa);
1515 dict_root(dict)->color = dnode_black;
1520 * Allocate a node using the dictionary's allocator routine, give it
1524 static dnode_t *dnode_init(dnode_t *dnode, void *data)
1527 dnode->parent = NULL;
1529 dnode->right = NULL;
1533 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
1535 dnode_t *node = malloc(sizeof(dnode_t));
1538 dnode_init(node, data);
1539 dict_insert(dict, node, key);
1546 * Return the node with the lowest (leftmost) key. If the dictionary is empty
1547 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
1550 static dnode_t *dict_first(dict_t *dict)
1552 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
1555 while ((left = root->left) != nil)
1558 return (root == nil) ? NULL : root;
1562 * Return the given node's successor node---the node which has the
1563 * next key in the the left to right ordering. If the node has
1564 * no successor, a null pointer is returned rather than a pointer to
1568 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
1570 dnode_t *nil = dict_nil(dict), *parent, *left;
1572 if (curr->right != nil) {
1574 while ((left = curr->left) != nil)
1579 parent = curr->parent;
1581 while (parent != nil && curr == parent->right) {
1583 parent = curr->parent;
1586 return (parent == nil) ? NULL : parent;
1590 static void dnode_free(dnode_t *node)
1610 * dirinfo.c --- maintains the directory information table for e2fsck.
1614 * This subroutine is called during pass1 to create a directory info
1615 * entry. During pass1, the passed-in parent is 0; it will get filled
1618 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
1620 struct dir_info *dir;
1622 ext2_ino_t num_dirs;
1624 unsigned long old_size;
1626 if (!ctx->dir_info) {
1627 ctx->dir_info_count = 0;
1628 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
1630 num_dirs = 1024; /* Guess */
1631 ctx->dir_info_size = num_dirs + 10;
1632 ctx->dir_info = (struct dir_info *)
1633 e2fsck_allocate_memory(ctx, ctx->dir_info_size
1634 * sizeof (struct dir_info),
1638 if (ctx->dir_info_count >= ctx->dir_info_size) {
1639 old_size = ctx->dir_info_size * sizeof(struct dir_info);
1640 ctx->dir_info_size += 10;
1641 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
1642 sizeof(struct dir_info),
1645 ctx->dir_info_size -= 10;
1651 * Normally, add_dir_info is called with each inode in
1652 * sequential order; but once in a while (like when pass 3
1653 * needs to recreate the root directory or lost+found
1654 * directory) it is called out of order. In those cases, we
1655 * need to move the dir_info entries down to make room, since
1656 * the dir_info array needs to be sorted by inode number for
1657 * get_dir_info()'s sake.
1659 if (ctx->dir_info_count &&
1660 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
1661 for (i = ctx->dir_info_count-1; i > 0; i--)
1662 if (ctx->dir_info[i-1].ino < ino)
1664 dir = &ctx->dir_info[i];
1665 if (dir->ino != ino)
1666 for (j = ctx->dir_info_count++; j > i; j--)
1667 ctx->dir_info[j] = ctx->dir_info[j-1];
1669 dir = &ctx->dir_info[ctx->dir_info_count++];
1672 dir->dotdot = parent;
1673 dir->parent = parent;
1677 * get_dir_info() --- given an inode number, try to find the directory
1678 * information entry for it.
1680 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
1685 high = ctx->dir_info_count-1;
1688 if (ino == ctx->dir_info[low].ino)
1689 return &ctx->dir_info[low];
1690 if (ino == ctx->dir_info[high].ino)
1691 return &ctx->dir_info[high];
1693 while (low < high) {
1695 if (mid == low || mid == high)
1697 if (ino == ctx->dir_info[mid].ino)
1698 return &ctx->dir_info[mid];
1699 if (ino < ctx->dir_info[mid].ino)
1708 * Free the dir_info structure when it isn't needed any more.
1710 static void e2fsck_free_dir_info(e2fsck_t ctx)
1712 ext2fs_free_mem(&ctx->dir_info);
1713 ctx->dir_info_size = 0;
1714 ctx->dir_info_count = 0;
1718 * Return the count of number of directories in the dir_info structure
1720 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
1722 return ctx->dir_info_count;
1726 * A simple interator function
1728 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
1730 if (*control >= ctx->dir_info_count)
1733 return(ctx->dir_info + (*control)++);
1737 * dirinfo.c --- maintains the directory information table for e2fsck.
1744 * This subroutine is called during pass1 to create a directory info
1745 * entry. During pass1, the passed-in parent is 0; it will get filled
1748 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
1750 struct dx_dir_info *dir;
1753 unsigned long old_size;
1755 if (!ctx->dx_dir_info) {
1756 ctx->dx_dir_info_count = 0;
1757 ctx->dx_dir_info_size = 100; /* Guess */
1758 ctx->dx_dir_info = (struct dx_dir_info *)
1759 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
1760 * sizeof (struct dx_dir_info),
1764 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
1765 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
1766 ctx->dx_dir_info_size += 10;
1767 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
1768 sizeof(struct dx_dir_info),
1771 ctx->dx_dir_info_size -= 10;
1777 * Normally, add_dx_dir_info is called with each inode in
1778 * sequential order; but once in a while (like when pass 3
1779 * needs to recreate the root directory or lost+found
1780 * directory) it is called out of order. In those cases, we
1781 * need to move the dx_dir_info entries down to make room, since
1782 * the dx_dir_info array needs to be sorted by inode number for
1783 * get_dx_dir_info()'s sake.
1785 if (ctx->dx_dir_info_count &&
1786 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
1787 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
1788 if (ctx->dx_dir_info[i-1].ino < ino)
1790 dir = &ctx->dx_dir_info[i];
1791 if (dir->ino != ino)
1792 for (j = ctx->dx_dir_info_count++; j > i; j--)
1793 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
1795 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
1798 dir->numblocks = num_blocks;
1799 dir->hashversion = 0;
1800 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
1801 * sizeof (struct dx_dirblock_info),
1802 "dx_block info array");
1807 * get_dx_dir_info() --- given an inode number, try to find the directory
1808 * information entry for it.
1810 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
1815 high = ctx->dx_dir_info_count-1;
1816 if (!ctx->dx_dir_info)
1818 if (ino == ctx->dx_dir_info[low].ino)
1819 return &ctx->dx_dir_info[low];
1820 if (ino == ctx->dx_dir_info[high].ino)
1821 return &ctx->dx_dir_info[high];
1823 while (low < high) {
1825 if (mid == low || mid == high)
1827 if (ino == ctx->dx_dir_info[mid].ino)
1828 return &ctx->dx_dir_info[mid];
1829 if (ino < ctx->dx_dir_info[mid].ino)
1838 * Free the dx_dir_info structure when it isn't needed any more.
1840 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
1843 struct dx_dir_info *dir;
1845 if (ctx->dx_dir_info) {
1846 dir = ctx->dx_dir_info;
1847 for (i=0; i < ctx->dx_dir_info_count; i++) {
1848 ext2fs_free_mem(&dir->dx_block);
1850 ext2fs_free_mem(&ctx->dx_dir_info);
1852 ctx->dx_dir_info_size = 0;
1853 ctx->dx_dir_info_count = 0;
1857 * A simple interator function
1859 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
1861 if (*control >= ctx->dx_dir_info_count)
1864 return(ctx->dx_dir_info + (*control)++);
1867 #endif /* ENABLE_HTREE */
1869 * e2fsck.c - a consistency checker for the new extended file system.
1874 * This function allocates an e2fsck context
1876 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1881 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1885 memset(context, 0, sizeof(struct e2fsck_struct));
1887 context->process_inode_size = 256;
1888 context->ext_attr_ver = 2;
1894 struct ea_refcount_el {
1899 struct ea_refcount {
1903 struct ea_refcount_el *list;
1906 static void ea_refcount_free(ext2_refcount_t refcount)
1911 ext2fs_free_mem(&refcount->list);
1912 ext2fs_free_mem(&refcount);
1916 * This function resets an e2fsck context; it is called when e2fsck
1917 * needs to be restarted.
1919 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1922 ctx->lost_and_found = 0;
1923 ctx->bad_lost_and_found = 0;
1924 ext2fs_free_inode_bitmap(ctx->inode_used_map);
1925 ctx->inode_used_map = 0;
1926 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1927 ctx->inode_dir_map = 0;
1928 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1929 ctx->inode_reg_map = 0;
1930 ext2fs_free_block_bitmap(ctx->block_found_map);
1931 ctx->block_found_map = 0;
1932 ext2fs_free_icount(ctx->inode_link_info);
1933 ctx->inode_link_info = 0;
1934 if (ctx->journal_io) {
1935 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1936 io_channel_close(ctx->journal_io);
1937 ctx->journal_io = 0;
1940 ext2fs_free_dblist(ctx->fs->dblist);
1941 ctx->fs->dblist = 0;
1943 e2fsck_free_dir_info(ctx);
1945 e2fsck_free_dx_dir_info(ctx);
1947 ea_refcount_free(ctx->refcount);
1949 ea_refcount_free(ctx->refcount_extra);
1950 ctx->refcount_extra = 0;
1951 ext2fs_free_block_bitmap(ctx->block_dup_map);
1952 ctx->block_dup_map = 0;
1953 ext2fs_free_block_bitmap(ctx->block_ea_map);
1954 ctx->block_ea_map = 0;
1955 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1956 ctx->inode_bb_map = 0;
1957 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1958 ctx->inode_bad_map = 0;
1959 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1960 ctx->inode_imagic_map = 0;
1961 ext2fs_u32_list_free(ctx->dirs_to_hash);
1962 ctx->dirs_to_hash = 0;
1965 * Clear the array of invalid meta-data flags
1967 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1968 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1969 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1971 /* Clear statistic counters */
1972 ctx->fs_directory_count = 0;
1973 ctx->fs_regular_count = 0;
1974 ctx->fs_blockdev_count = 0;
1975 ctx->fs_chardev_count = 0;
1976 ctx->fs_links_count = 0;
1977 ctx->fs_symlinks_count = 0;
1978 ctx->fs_fast_symlinks_count = 0;
1979 ctx->fs_fifo_count = 0;
1980 ctx->fs_total_count = 0;
1981 ctx->fs_badblocks_count = 0;
1982 ctx->fs_sockets_count = 0;
1983 ctx->fs_ind_count = 0;
1984 ctx->fs_dind_count = 0;
1985 ctx->fs_tind_count = 0;
1986 ctx->fs_fragmented = 0;
1987 ctx->large_files = 0;
1989 /* Reset the superblock to the user's requested value */
1990 ctx->superblock = ctx->use_superblock;
1995 static void e2fsck_free_context(e2fsck_t ctx)
2000 e2fsck_reset_context(ctx);
2002 blkid_put_cache(ctx->blkid);
2004 ext2fs_free_mem(&ctx);
2012 * The strategy we use for keeping track of EA refcounts is as
2013 * follows. We keep a sorted array of first EA blocks and its
2014 * reference counts. Once the refcount has dropped to zero, it is
2015 * removed from the array to save memory space. Once the EA block is
2016 * checked, its bit is set in the block_ea_map bitmap.
2020 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
2022 ext2_refcount_t refcount;
2026 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
2029 memset(refcount, 0, sizeof(struct ea_refcount));
2033 refcount->size = size;
2034 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
2036 printf("Refcount allocated %d entries, %d bytes.\n",
2037 refcount->size, bytes);
2039 retval = ext2fs_get_mem(bytes, &refcount->list);
2042 memset(refcount->list, 0, bytes);
2044 refcount->count = 0;
2045 refcount->cursor = 0;
2051 ea_refcount_free(refcount);
2056 * collapse_refcount() --- go through the refcount array, and get rid
2057 * of any count == zero entries
2059 static void refcount_collapse(ext2_refcount_t refcount)
2062 struct ea_refcount_el *list;
2064 list = refcount->list;
2065 for (i = 0, j = 0; i < refcount->count; i++) {
2066 if (list[i].ea_count) {
2072 #if defined(DEBUG) || defined(TEST_PROGRAM)
2073 printf("Refcount_collapse: size was %d, now %d\n",
2074 refcount->count, j);
2076 refcount->count = j;
2081 * insert_refcount_el() --- Insert a new entry into the sorted list at a
2082 * specified position.
2084 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
2087 struct ea_refcount_el *el;
2092 if (refcount->count >= refcount->size) {
2093 new_size = refcount->size + 100;
2095 printf("Reallocating refcount %d entries...\n", new_size);
2097 retval = ext2fs_resize_mem((size_t) refcount->size *
2098 sizeof(struct ea_refcount_el),
2100 sizeof(struct ea_refcount_el),
2104 refcount->size = new_size;
2106 num = (int) refcount->count - pos;
2108 return 0; /* should never happen */
2110 memmove(&refcount->list[pos+1], &refcount->list[pos],
2111 sizeof(struct ea_refcount_el) * num);
2114 el = &refcount->list[pos];
2122 * get_refcount_el() --- given an block number, try to find refcount
2123 * information in the sorted list. If the create flag is set,
2124 * and we can't find an entry, create one in the sorted list.
2126 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
2127 blk_t blk, int create)
2131 blk_t lowval, highval;
2133 if (!refcount || !refcount->list)
2137 high = (int) refcount->count-1;
2138 if (create && ((refcount->count == 0) ||
2139 (blk > refcount->list[high].ea_blk))) {
2140 if (refcount->count >= refcount->size)
2141 refcount_collapse(refcount);
2143 return insert_refcount_el(refcount, blk,
2144 (unsigned) refcount->count);
2146 if (refcount->count == 0)
2149 if (refcount->cursor >= refcount->count)
2150 refcount->cursor = 0;
2151 if (blk == refcount->list[refcount->cursor].ea_blk)
2152 return &refcount->list[refcount->cursor++];
2154 printf("Non-cursor get_refcount_el: %u\n", blk);
2156 while (low <= high) {
2160 /* Interpolate for efficiency */
2161 lowval = refcount->list[low].ea_blk;
2162 highval = refcount->list[high].ea_blk;
2166 else if (blk > highval)
2169 range = ((float) (blk - lowval)) /
2171 mid = low + ((int) (range * (high-low)));
2174 if (blk == refcount->list[mid].ea_blk) {
2175 refcount->cursor = mid+1;
2176 return &refcount->list[mid];
2178 if (blk < refcount->list[mid].ea_blk)
2184 * If we need to create a new entry, it should be right at
2185 * low (where high will be left at low-1).
2188 if (refcount->count >= refcount->size) {
2189 refcount_collapse(refcount);
2190 if (refcount->count < refcount->size)
2193 return insert_refcount_el(refcount, blk, low);
2199 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
2201 struct ea_refcount_el *el;
2203 el = get_refcount_el(refcount, blk, 1);
2205 return EXT2_ET_NO_MEMORY;
2209 *ret = el->ea_count;
2214 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
2216 struct ea_refcount_el *el;
2218 el = get_refcount_el(refcount, blk, 0);
2219 if (!el || el->ea_count == 0)
2220 return EXT2_ET_INVALID_ARGUMENT;
2225 *ret = el->ea_count;
2230 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
2232 struct ea_refcount_el *el;
2235 * Get the refcount element
2237 el = get_refcount_el(refcount, blk, count ? 1 : 0);
2239 return count ? EXT2_ET_NO_MEMORY : 0;
2240 el->ea_count = count;
2244 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
2246 refcount->cursor = 0;
2250 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
2252 struct ea_refcount_el *list;
2255 if (refcount->cursor >= refcount->count)
2257 list = refcount->list;
2258 if (list[refcount->cursor].ea_count) {
2260 *ret = list[refcount->cursor].ea_count;
2261 return list[refcount->cursor++].ea_blk;
2269 * ehandler.c --- handle bad block errors which come up during the
2270 * course of an e2fsck session.
2274 static const char *operation;
2277 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
2278 void *data, size_t size FSCK_ATTR((unused)),
2279 int actual FSCK_ATTR((unused)), errcode_t error)
2283 ext2_filsys fs = (ext2_filsys) channel->app_data;
2286 ctx = (e2fsck_t) fs->priv_data;
2289 * If more than one block was read, try reading each block
2290 * separately. We could use the actual bytes read to figure
2291 * out where to start, but we don't bother.
2295 for (i=0; i < count; i++, p += channel->block_size, block++) {
2296 error = io_channel_read_blk(channel, block,
2304 printf(_("Error reading block %lu (%s) while %s. "), block,
2305 error_message(error), operation);
2307 printf(_("Error reading block %lu (%s). "), block,
2308 error_message(error));
2310 if (ask(ctx, _("Ignore error"), 1)) {
2311 if (ask(ctx, _("Force rewrite"), 1))
2312 io_channel_write_blk(channel, block, 1, data);
2320 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
2321 const void *data, size_t size FSCK_ATTR((unused)),
2322 int actual FSCK_ATTR((unused)), errcode_t error)
2326 ext2_filsys fs = (ext2_filsys) channel->app_data;
2329 ctx = (e2fsck_t) fs->priv_data;
2332 * If more than one block was written, try writing each block
2333 * separately. We could use the actual bytes read to figure
2334 * out where to start, but we don't bother.
2337 p = (const char *) data;
2338 for (i=0; i < count; i++, p += channel->block_size, block++) {
2339 error = io_channel_write_blk(channel, block,
2348 printf(_("Error writing block %lu (%s) while %s. "), block,
2349 error_message(error), operation);
2351 printf(_("Error writing block %lu (%s). "), block,
2352 error_message(error));
2354 if (ask(ctx, _("Ignore error"), 1))
2360 static inline const char *ehandler_operation(const char *op)
2362 const char *ret = operation;
2368 static void ehandler_init(io_channel channel)
2370 channel->read_error = e2fsck_handle_read_error;
2371 channel->write_error = e2fsck_handle_write_error;
2375 * journal.c --- code for handling the "ext3" journal
2377 * Copyright (C) 2000 Andreas Dilger
2378 * Copyright (C) 2000 Theodore Ts'o
2380 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
2381 * Copyright (C) 1999 Red Hat Software
2383 * This file may be redistributed under the terms of the
2384 * GNU General Public License version 2 or at your discretion
2385 * any later version.
2388 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
2391 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
2392 * This creates a larger static binary, and a smaller binary using
2393 * shared libraries. It's also probably slightly less CPU-efficient,
2394 * which is why it's not on by default. But, it's a good way of
2395 * testing the functions in inode_io.c and fileio.c.
2399 /* Kernel compatibility functions for handling the journal. These allow us
2400 * to use the recovery.c file virtually unchanged from the kernel, so we
2401 * don't have to do much to keep kernel and user recovery in sync.
2403 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
2409 struct inode *inode = journal->j_inode;
2418 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
2419 &inode->i_ext2, NULL, 0, block, &pblk);
2425 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
2427 struct buffer_head *bh;
2429 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
2433 bh->b_ctx = kdev->k_ctx;
2434 if (kdev->k_dev == K_DEV_FS)
2435 bh->b_io = kdev->k_ctx->fs->io;
2437 bh->b_io = kdev->k_ctx->journal_io;
2438 bh->b_size = blocksize;
2439 bh->b_blocknr = blocknr;
2444 static void sync_blockdev(kdev_t kdev)
2448 if (kdev->k_dev == K_DEV_FS)
2449 io = kdev->k_ctx->fs->io;
2451 io = kdev->k_ctx->journal_io;
2453 io_channel_flush(io);
2456 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
2459 struct buffer_head *bh;
2461 for (; nr > 0; --nr) {
2463 if (rw == READ && !bh->b_uptodate) {
2464 retval = io_channel_read_blk(bh->b_io,
2468 com_err(bh->b_ctx->device_name, retval,
2469 "while reading block %lu\n",
2470 (unsigned long) bh->b_blocknr);
2475 } else if (rw == WRITE && bh->b_dirty) {
2476 retval = io_channel_write_blk(bh->b_io,
2480 com_err(bh->b_ctx->device_name, retval,
2481 "while writing block %lu\n",
2482 (unsigned long) bh->b_blocknr);
2492 static inline void mark_buffer_dirty(struct buffer_head *bh)
2497 static inline void mark_buffer_clean(struct buffer_head * bh)
2502 static void brelse(struct buffer_head *bh)
2505 ll_rw_block(WRITE, 1, &bh);
2506 ext2fs_free_mem(&bh);
2509 static inline int buffer_uptodate(struct buffer_head *bh)
2511 return bh->b_uptodate;
2514 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
2516 bh->b_uptodate = val;
2519 static void wait_on_buffer(struct buffer_head *bh)
2521 if (!bh->b_uptodate)
2522 ll_rw_block(READ, 1, &bh);
2526 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
2528 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
2530 /* if we had an error doing journal recovery, we need a full fsck */
2532 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
2533 ext2fs_mark_super_dirty(ctx->fs);
2536 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
2538 struct ext2_super_block *sb = ctx->fs->super;
2539 struct ext2_super_block jsuper;
2540 struct problem_context pctx;
2541 struct buffer_head *bh;
2542 struct inode *j_inode = NULL;
2543 struct kdev_s *dev_fs = NULL, *dev_journal;
2544 const char *journal_name = 0;
2545 journal_t *journal = NULL;
2546 errcode_t retval = 0;
2547 io_manager io_ptr = 0;
2548 unsigned long start = 0;
2550 int ext_journal = 0;
2551 int tried_backup_jnl = 0;
2554 clear_problem_context(&pctx);
2556 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
2558 return EXT2_ET_NO_MEMORY;
2561 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
2563 retval = EXT2_ET_NO_MEMORY;
2566 dev_journal = dev_fs+1;
2568 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
2569 dev_fs->k_dev = K_DEV_FS;
2570 dev_journal->k_dev = K_DEV_JOURNAL;
2572 journal->j_dev = dev_journal;
2573 journal->j_fs_dev = dev_fs;
2574 journal->j_inode = NULL;
2575 journal->j_blocksize = ctx->fs->blocksize;
2577 if (uuid_is_null(sb->s_journal_uuid)) {
2578 if (!sb->s_journal_inum)
2579 return EXT2_ET_BAD_INODE_NUM;
2580 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
2583 retval = EXT2_ET_NO_MEMORY;
2587 j_inode->i_ctx = ctx;
2588 j_inode->i_ino = sb->s_journal_inum;
2590 if ((retval = ext2fs_read_inode(ctx->fs,
2592 &j_inode->i_ext2))) {
2594 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
2597 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
2598 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
2600 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
2601 j_inode->i_ext2.i_links_count = 1;
2602 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
2605 if (!j_inode->i_ext2.i_links_count ||
2606 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
2607 retval = EXT2_ET_NO_JOURNAL;
2608 goto try_backup_journal;
2610 if (j_inode->i_ext2.i_size / journal->j_blocksize <
2611 JFS_MIN_JOURNAL_BLOCKS) {
2612 retval = EXT2_ET_JOURNAL_TOO_SMALL;
2613 goto try_backup_journal;
2615 for (i=0; i < EXT2_N_BLOCKS; i++) {
2616 blk = j_inode->i_ext2.i_block[i];
2618 if (i < EXT2_NDIR_BLOCKS) {
2619 retval = EXT2_ET_JOURNAL_TOO_SMALL;
2620 goto try_backup_journal;
2624 if (blk < sb->s_first_data_block ||
2625 blk >= sb->s_blocks_count) {
2626 retval = EXT2_ET_BAD_BLOCK_NUM;
2627 goto try_backup_journal;
2630 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
2633 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
2639 io_ptr = inode_io_manager;
2641 journal->j_inode = j_inode;
2642 ctx->journal_io = ctx->fs->io;
2643 if ((retval = journal_bmap(journal, 0, &start)) != 0)
2648 if (!ctx->journal_name) {
2651 uuid_unparse(sb->s_journal_uuid, uuid);
2652 ctx->journal_name = blkid_get_devname(ctx->blkid,
2654 if (!ctx->journal_name)
2655 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
2657 journal_name = ctx->journal_name;
2659 if (!journal_name) {
2660 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
2661 return EXT2_ET_LOAD_EXT_JOURNAL;
2664 io_ptr = unix_io_manager;
2667 #ifndef USE_INODE_IO
2670 retval = io_ptr->open(journal_name, IO_FLAG_RW,
2675 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
2678 if (ctx->fs->blocksize == 1024)
2680 bh = getblk(dev_journal, start, ctx->fs->blocksize);
2682 retval = EXT2_ET_NO_MEMORY;
2685 ll_rw_block(READ, 1, &bh);
2686 if ((retval = bh->b_err) != 0)
2688 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
2691 #ifdef EXT2FS_ENABLE_SWAPFS
2692 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
2693 ext2fs_swap_super(&jsuper);
2695 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
2696 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
2697 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
2698 retval = EXT2_ET_LOAD_EXT_JOURNAL;
2701 /* Make sure the journal UUID is correct */
2702 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
2703 sizeof(jsuper.s_uuid))) {
2704 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
2705 retval = EXT2_ET_LOAD_EXT_JOURNAL;
2709 journal->j_maxlen = jsuper.s_blocks_count;
2713 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
2714 retval = EXT2_ET_NO_MEMORY;
2718 journal->j_sb_buffer = bh;
2719 journal->j_superblock = (journal_superblock_t *)bh->b_data;
2722 ext2fs_free_mem(&j_inode);
2725 *ret_journal = journal;
2729 ext2fs_free_mem(&dev_fs);
2730 ext2fs_free_mem(&j_inode);
2731 ext2fs_free_mem(&journal);
2736 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
2737 struct problem_context *pctx)
2739 struct ext2_super_block *sb = ctx->fs->super;
2740 int recover = ctx->fs->super->s_feature_incompat &
2741 EXT3_FEATURE_INCOMPAT_RECOVER;
2742 int has_journal = ctx->fs->super->s_feature_compat &
2743 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2745 if (has_journal || sb->s_journal_inum) {
2746 /* The journal inode is bogus, remove and force full fsck */
2747 pctx->ino = sb->s_journal_inum;
2748 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
2749 if (has_journal && sb->s_journal_inum)
2750 printf("*** ext3 journal has been deleted - "
2751 "filesystem is now ext2 only ***\n\n");
2752 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2753 sb->s_journal_inum = 0;
2754 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
2755 e2fsck_clear_recover(ctx, 1);
2758 return EXT2_ET_BAD_INODE_NUM;
2759 } else if (recover) {
2760 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
2761 e2fsck_clear_recover(ctx, 1);
2764 return EXT2_ET_UNSUPP_FEATURE;
2769 #define V1_SB_SIZE 0x0024
2770 static void clear_v2_journal_fields(journal_t *journal)
2772 e2fsck_t ctx = journal->j_dev->k_ctx;
2773 struct problem_context pctx;
2775 clear_problem_context(&pctx);
2777 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
2780 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
2781 ctx->fs->blocksize-V1_SB_SIZE);
2782 mark_buffer_dirty(journal->j_sb_buffer);
2786 static errcode_t e2fsck_journal_load(journal_t *journal)
2788 e2fsck_t ctx = journal->j_dev->k_ctx;
2789 journal_superblock_t *jsb;
2790 struct buffer_head *jbh = journal->j_sb_buffer;
2791 struct problem_context pctx;
2793 clear_problem_context(&pctx);
2795 ll_rw_block(READ, 1, &jbh);
2797 com_err(ctx->device_name, jbh->b_err,
2798 _("reading journal superblock\n"));
2802 jsb = journal->j_superblock;
2803 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
2804 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
2805 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2807 switch (ntohl(jsb->s_header.h_blocktype)) {
2808 case JFS_SUPERBLOCK_V1:
2809 journal->j_format_version = 1;
2810 if (jsb->s_feature_compat ||
2811 jsb->s_feature_incompat ||
2812 jsb->s_feature_ro_compat ||
2814 clear_v2_journal_fields(journal);
2817 case JFS_SUPERBLOCK_V2:
2818 journal->j_format_version = 2;
2819 if (ntohl(jsb->s_nr_users) > 1 &&
2820 uuid_is_null(ctx->fs->super->s_journal_uuid))
2821 clear_v2_journal_fields(journal);
2822 if (ntohl(jsb->s_nr_users) > 1) {
2823 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
2824 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
2829 * These should never appear in a journal super block, so if
2830 * they do, the journal is badly corrupted.
2832 case JFS_DESCRIPTOR_BLOCK:
2833 case JFS_COMMIT_BLOCK:
2834 case JFS_REVOKE_BLOCK:
2835 return EXT2_ET_CORRUPT_SUPERBLOCK;
2837 /* If we don't understand the superblock major type, but there
2838 * is a magic number, then it is likely to be a new format we
2839 * just don't understand, so leave it alone. */
2841 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
2844 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
2845 return EXT2_ET_UNSUPP_FEATURE;
2847 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
2848 return EXT2_ET_RO_UNSUPP_FEATURE;
2850 /* We have now checked whether we know enough about the journal
2851 * format to be able to proceed safely, so any other checks that
2852 * fail we should attempt to recover from. */
2853 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
2854 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2855 _("%s: no valid journal superblock found\n"),
2857 return EXT2_ET_CORRUPT_SUPERBLOCK;
2860 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
2861 journal->j_maxlen = ntohl(jsb->s_maxlen);
2862 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
2863 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2864 _("%s: journal too short\n"),
2866 return EXT2_ET_CORRUPT_SUPERBLOCK;
2869 journal->j_tail_sequence = ntohl(jsb->s_sequence);
2870 journal->j_transaction_sequence = journal->j_tail_sequence;
2871 journal->j_tail = ntohl(jsb->s_start);
2872 journal->j_first = ntohl(jsb->s_first);
2873 journal->j_last = ntohl(jsb->s_maxlen);
2878 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2889 /* Leave a valid existing V1 superblock signature alone.
2890 * Anything unrecognisable we overwrite with a new V2
2893 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2894 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2895 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2896 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2899 /* Zero out everything else beyond the superblock header */
2901 p = ((char *) jsb) + sizeof(journal_header_t);
2902 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2904 jsb->s_blocksize = htonl(ctx->fs->blocksize);
2905 jsb->s_maxlen = htonl(journal->j_maxlen);
2906 jsb->s_first = htonl(1);
2908 /* Initialize the journal sequence number so that there is "no"
2909 * chance we will find old "valid" transactions in the journal.
2910 * This avoids the need to zero the whole journal (slow to do,
2911 * and risky when we are just recovering the filesystem).
2913 uuid_generate(u.uuid);
2914 for (i = 0; i < 4; i ++)
2915 new_seq ^= u.val[i];
2916 jsb->s_sequence = htonl(new_seq);
2918 mark_buffer_dirty(journal->j_sb_buffer);
2919 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2922 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2924 struct problem_context *pctx)
2926 struct ext2_super_block *sb = ctx->fs->super;
2927 int recover = ctx->fs->super->s_feature_incompat &
2928 EXT3_FEATURE_INCOMPAT_RECOVER;
2930 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2931 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2932 e2fsck_journal_reset_super(ctx, journal->j_superblock,
2934 journal->j_transaction_sequence = 1;
2935 e2fsck_clear_recover(ctx, recover);
2938 return EXT2_ET_CORRUPT_SUPERBLOCK;
2939 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2940 return EXT2_ET_CORRUPT_SUPERBLOCK;
2945 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2946 int reset, int drop)
2948 journal_superblock_t *jsb;
2951 mark_buffer_clean(journal->j_sb_buffer);
2952 else if (!(ctx->options & E2F_OPT_READONLY)) {
2953 jsb = journal->j_superblock;
2954 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2956 jsb->s_start = 0; /* this marks the journal as empty */
2957 mark_buffer_dirty(journal->j_sb_buffer);
2959 brelse(journal->j_sb_buffer);
2961 if (ctx->journal_io) {
2962 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2963 io_channel_close(ctx->journal_io);
2964 ctx->journal_io = 0;
2967 #ifndef USE_INODE_IO
2968 ext2fs_free_mem(&journal->j_inode);
2970 ext2fs_free_mem(&journal->j_fs_dev);
2971 ext2fs_free_mem(&journal);
2975 * This function makes sure that the superblock fields regarding the
2976 * journal are consistent.
2978 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2980 struct ext2_super_block *sb = ctx->fs->super;
2982 int recover = ctx->fs->super->s_feature_incompat &
2983 EXT3_FEATURE_INCOMPAT_RECOVER;
2984 struct problem_context pctx;
2986 int reset = 0, force_fsck = 0;
2989 /* If we don't have any journal features, don't do anything more */
2990 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2991 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2992 uuid_is_null(sb->s_journal_uuid))
2995 clear_problem_context(&pctx);
2996 pctx.num = sb->s_journal_inum;
2998 retval = e2fsck_get_journal(ctx, &journal);
3000 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
3001 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
3002 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
3003 (retval == EXT2_ET_NO_JOURNAL))
3004 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3008 retval = e2fsck_journal_load(journal);
3010 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
3011 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
3012 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
3014 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
3015 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
3017 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
3018 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
3019 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
3021 e2fsck_journal_release(ctx, journal, 0, 1);
3026 * We want to make the flags consistent here. We will not leave with
3027 * needs_recovery set but has_journal clear. We can't get in a loop
3028 * with -y, -n, or -p, only if a user isn't making up their mind.
3031 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
3032 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
3034 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
3036 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
3037 goto no_has_journal;
3039 * Need a full fsck if we are releasing a
3040 * journal stored on a reserved inode.
3042 force_fsck = recover ||
3043 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
3044 /* Clear all of the journal fields */
3045 sb->s_journal_inum = 0;
3046 sb->s_journal_dev = 0;
3047 memset(sb->s_journal_uuid, 0,
3048 sizeof(sb->s_journal_uuid));
3049 e2fsck_clear_recover(ctx, force_fsck);
3050 } else if (!(ctx->options & E2F_OPT_READONLY)) {
3051 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3052 ext2fs_mark_super_dirty(ctx->fs);
3056 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
3057 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
3058 journal->j_superblock->s_start != 0) {
3059 /* Print status information */
3060 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
3061 if (ctx->superblock)
3062 problem = PR_0_JOURNAL_RUN_DEFAULT;
3064 problem = PR_0_JOURNAL_RUN;
3065 if (fix_problem(ctx, problem, &pctx)) {
3066 ctx->options |= E2F_OPT_FORCE;
3067 sb->s_feature_incompat |=
3068 EXT3_FEATURE_INCOMPAT_RECOVER;
3069 ext2fs_mark_super_dirty(ctx->fs);
3070 } else if (fix_problem(ctx,
3071 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
3073 sb->s_state &= ~EXT2_VALID_FS;
3074 ext2fs_mark_super_dirty(ctx->fs);
3077 * If the user answers no to the above question, we
3078 * ignore the fact that journal apparently has data;
3079 * accidentally replaying over valid data would be far
3080 * worse than skipping a questionable recovery.
3082 * XXX should we abort with a fatal error here? What
3083 * will the ext3 kernel code do if a filesystem with
3084 * !NEEDS_RECOVERY but with a non-zero
3085 * journal->j_superblock->s_start is mounted?
3089 e2fsck_journal_release(ctx, journal, reset, 0);
3093 static errcode_t recover_ext3_journal(e2fsck_t ctx)
3098 journal_init_revoke_caches();
3099 retval = e2fsck_get_journal(ctx, &journal);
3103 retval = e2fsck_journal_load(journal);
3107 retval = journal_init_revoke(journal, 1024);
3111 retval = -journal_recover(journal);
3115 if (journal->j_superblock->s_errno) {
3116 ctx->fs->super->s_state |= EXT2_ERROR_FS;
3117 ext2fs_mark_super_dirty(ctx->fs);
3118 journal->j_superblock->s_errno = 0;
3119 mark_buffer_dirty(journal->j_sb_buffer);
3123 journal_destroy_revoke(journal);
3124 journal_destroy_revoke_caches();
3125 e2fsck_journal_release(ctx, journal, 1, 0);
3129 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
3131 io_manager io_ptr = ctx->fs->io->manager;
3132 int blocksize = ctx->fs->blocksize;
3133 errcode_t retval, recover_retval;
3135 printf(_("%s: recovering journal\n"), ctx->device_name);
3136 if (ctx->options & E2F_OPT_READONLY) {
3137 printf(_("%s: won't do journal recovery while read-only\n"),
3139 return EXT2_ET_FILE_RO;
3142 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
3143 ext2fs_flush(ctx->fs); /* Force out any modifications */
3145 recover_retval = recover_ext3_journal(ctx);
3148 * Reload the filesystem context to get up-to-date data from disk
3149 * because journal recovery will change the filesystem under us.
3151 ext2fs_close(ctx->fs);
3152 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
3153 ctx->superblock, blocksize, io_ptr,
3157 com_err(ctx->program_name, retval,
3158 _("while trying to re-open %s"),
3160 fatal_error(ctx, 0);
3162 ctx->fs->priv_data = ctx;
3164 /* Set the superblock flags */
3165 e2fsck_clear_recover(ctx, recover_retval);
3166 return recover_retval;
3170 * This function will move the journal inode from a visible file in
3171 * the filesystem directory hierarchy to the reserved inode if necessary.
3173 static const char * const journal_names[] = {
3174 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
3176 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
3178 struct ext2_super_block *sb = ctx->fs->super;
3179 struct problem_context pctx;
3180 struct ext2_inode inode;
3181 ext2_filsys fs = ctx->fs;
3184 const char * const * cpp;
3185 int group, mount_flags;
3187 clear_problem_context(&pctx);
3190 * If the filesystem is opened read-only, or there is no
3191 * journal, then do nothing.
3193 if ((ctx->options & E2F_OPT_READONLY) ||
3194 (sb->s_journal_inum == 0) ||
3195 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
3199 * Read in the journal inode
3201 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
3205 * If it's necessary to backup the journal inode, do so.
3207 if ((sb->s_jnl_backup_type == 0) ||
3208 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
3209 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
3210 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
3211 memcpy(sb->s_jnl_blocks, inode.i_block,
3213 sb->s_jnl_blocks[16] = inode.i_size;
3214 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
3215 ext2fs_mark_super_dirty(fs);
3216 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3221 * If the journal is already the hidden inode, then do nothing
3223 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
3227 * The journal inode had better have only one link and not be readable.
3229 if (inode.i_links_count != 1)
3233 * If the filesystem is mounted, or we can't tell whether
3234 * or not it's mounted, do nothing.
3236 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
3237 if (retval || (mount_flags & EXT2_MF_MOUNTED))
3241 * If we can't find the name of the journal inode, then do
3244 for (cpp = journal_names; *cpp; cpp++) {
3245 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
3246 strlen(*cpp), 0, &ino);
3247 if ((retval == 0) && (ino == sb->s_journal_inum))
3253 /* We need the inode bitmap to be loaded */
3254 retval = ext2fs_read_bitmaps(fs);
3259 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
3263 * OK, we've done all the checks, let's actually move the
3264 * journal inode. Errors at this point mean we need to force
3265 * an ext2 filesystem check.
3267 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
3269 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
3271 sb->s_journal_inum = EXT2_JOURNAL_INO;
3272 ext2fs_mark_super_dirty(fs);
3273 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3274 inode.i_links_count = 0;
3275 inode.i_dtime = time(0);
3276 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
3279 group = ext2fs_group_of_ino(fs, ino);
3280 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
3281 ext2fs_mark_ib_dirty(fs);
3282 fs->group_desc[group].bg_free_inodes_count++;
3283 fs->super->s_free_inodes_count++;
3287 pctx.errcode = retval;
3288 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
3289 fs->super->s_state &= ~EXT2_VALID_FS;
3290 ext2fs_mark_super_dirty(fs);
3295 * message.c --- print e2fsck messages (with compression)
3297 * print_e2fsck_message() prints a message to the user, using
3298 * compression techniques and expansions of abbreviations.
3300 * The following % expansions are supported:
3302 * %b <blk> block number
3303 * %B <blkcount> integer
3304 * %c <blk2> block number
3305 * %Di <dirent>->ino inode number
3306 * %Dn <dirent>->name string
3307 * %Dr <dirent>->rec_len
3308 * %Dl <dirent>->name_len
3309 * %Dt <dirent>->filetype
3310 * %d <dir> inode number
3311 * %g <group> integer
3312 * %i <ino> inode number
3313 * %Is <inode> -> i_size
3314 * %IS <inode> -> i_extra_isize
3315 * %Ib <inode> -> i_blocks
3316 * %Il <inode> -> i_links_count
3317 * %Im <inode> -> i_mode
3318 * %IM <inode> -> i_mtime
3319 * %IF <inode> -> i_faddr
3320 * %If <inode> -> i_file_acl
3321 * %Id <inode> -> i_dir_acl
3322 * %Iu <inode> -> i_uid
3323 * %Ig <inode> -> i_gid
3324 * %j <ino2> inode number
3325 * %m <com_err error message>
3327 * %p ext2fs_get_pathname of directory <ino>
3328 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
3329 * the containing directory. (If dirent is NULL
3330 * then return the pathname of directory <ino2>)
3331 * %q ext2fs_get_pathname of directory <dir>
3332 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
3333 * the containing directory.
3334 * %s <str> miscellaneous string
3335 * %S backup superblock
3336 * %X <num> hexadecimal format
3338 * The following '@' expansions are supported:
3340 * @a extended attribute
3341 * @A error allocating
3345 * @C conflicts with some other fs block
3349 * @E Entry '%Dn' in %p (%i)
3351 * @F for @i %i (%Q) is
3353 * @h HTREE directory inode
3359 * @m multiply-claimed
3373 * This structure defines the abbreviations used by the text strings
3374 * below. The first character in the string is the index letter. An
3375 * abbreviation of the form '@<i>' is expanded by looking up the index
3376 * letter <i> in the table below.
3378 static const char * const abbrevs[] = {
3379 N_("aextended attribute"),
3380 N_("Aerror allocating"),
3384 N_("Cconflicts with some other fs @b"),
3391 N_("E@e '%Dn' in %p (%i)"),
3393 N_("Ffor @i %i (%Q) is"),
3398 N_("mmultiply-claimed"),
3413 * Give more user friendly names to the "special" inodes.
3415 #define num_special_inodes 11
3416 static const char * const special_inode_name[] =
3418 N_("<The NULL inode>"), /* 0 */
3419 N_("<The bad blocks inode>"), /* 1 */
3421 N_("<The ACL index inode>"), /* 3 */
3422 N_("<The ACL data inode>"), /* 4 */
3423 N_("<The boot loader inode>"), /* 5 */
3424 N_("<The undelete directory inode>"), /* 6 */
3425 N_("<The group descriptor inode>"), /* 7 */
3426 N_("<The journal inode>"), /* 8 */
3427 N_("<Reserved inode 9>"), /* 9 */
3428 N_("<Reserved inode 10>"), /* 10 */
3432 * This function does "safe" printing. It will convert non-printable
3433 * ASCII characters using '^' and M- notation.
3435 static void safe_print(const char *cp, int len)
3445 fputs("M-", stdout);
3448 if ((ch < 32) || (ch == 0x7f)) {
3450 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
3458 * This function prints a pathname, using the ext2fs_get_pathname
3461 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
3466 if (!dir && (ino < num_special_inodes)) {
3467 fputs(_(special_inode_name[ino]), stdout);
3471 retval = ext2fs_get_pathname(fs, dir, ino, &path);
3473 fputs("???", stdout);
3475 safe_print(path, -1);
3476 ext2fs_free_mem(&path);
3480 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
3481 struct problem_context *pctx, int first);
3483 * This function handles the '@' expansion. We allow recursive
3484 * expansion; an @ expression can contain further '@' and '%'
3487 static void expand_at_expression(e2fsck_t ctx, char ch,
3488 struct problem_context *pctx,
3491 const char * const *cpp;
3494 /* Search for the abbreviation */
3495 for (cpp = abbrevs; *cpp; cpp++) {
3501 if (*first && islower(*str)) {
3503 fputc(toupper(*str++), stdout);
3505 print_e2fsck_message(ctx, str, pctx, *first);
3511 * This function expands '%IX' expressions
3513 static void expand_inode_expression(char ch,
3514 struct problem_context *ctx)
3516 struct ext2_inode *inode;
3517 struct ext2_inode_large *large_inode;
3522 if (!ctx || !ctx->inode)
3526 large_inode = (struct ext2_inode_large *) inode;
3530 if (LINUX_S_ISDIR(inode->i_mode))
3531 printf("%u", inode->i_size);
3533 #ifdef EXT2_NO_64_TYPE
3534 if (inode->i_size_high)
3535 printf("0x%x%08x", inode->i_size_high,
3538 printf("%u", inode->i_size);
3540 printf("%llu", (inode->i_size |
3541 ((__u64) inode->i_size_high << 32)));
3546 printf("%u", large_inode->i_extra_isize);
3549 printf("%u", inode->i_blocks);
3552 printf("%d", inode->i_links_count);
3555 printf("0%o", inode->i_mode);
3558 /* The diet libc doesn't respect the TZ environemnt variable */
3560 time_str = getenv("TZ");
3563 do_gmt = !strcmp(time_str, "GMT");
3566 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
3567 printf("%.24s", time_str);
3570 printf("%u", inode->i_faddr);
3573 printf("%u", inode->i_file_acl);
3576 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
3577 inode->i_dir_acl : 0));
3580 printf("%d", (inode->i_uid |
3581 (inode->osd2.linux2.l_i_uid_high << 16)));
3584 printf("%d", (inode->i_gid |
3585 (inode->osd2.linux2.l_i_gid_high << 16)));
3589 printf("%%I%c", ch);
3595 * This function expands '%dX' expressions
3597 static _INLINE_ void expand_dirent_expression(char ch,
3598 struct problem_context *ctx)
3600 struct ext2_dir_entry *dirent;
3603 if (!ctx || !ctx->dirent)
3606 dirent = ctx->dirent;
3610 printf("%u", dirent->inode);
3613 len = dirent->name_len & 0xFF;
3614 if (len > EXT2_NAME_LEN)
3615 len = EXT2_NAME_LEN;
3616 if (len > dirent->rec_len)
3617 len = dirent->rec_len;
3618 safe_print(dirent->name, len);
3621 printf("%u", dirent->rec_len);
3624 printf("%u", dirent->name_len & 0xFF);
3627 printf("%u", dirent->name_len >> 8);
3631 printf("%%D%c", ch);
3636 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
3637 struct problem_context *ctx)
3647 printf("%u", ctx->blk);
3650 #ifdef EXT2_NO_64_TYPE
3651 printf("%d", ctx->blkcount);
3653 printf("%lld", ctx->blkcount);
3657 printf("%u", ctx->blk2);
3660 printf("%u", ctx->dir);
3663 printf("%d", ctx->group);
3666 printf("%u", ctx->ino);
3669 printf("%u", ctx->ino2);
3672 printf("%s", error_message(ctx->errcode));
3675 #ifdef EXT2_NO_64_TYPE
3676 printf("%u", ctx->num);
3678 printf("%llu", ctx->num);
3682 print_pathname(fs, ctx->ino, 0);
3685 print_pathname(fs, ctx->ino2,
3686 ctx->dirent ? ctx->dirent->inode : 0);
3689 print_pathname(fs, ctx->dir, 0);
3692 print_pathname(fs, ctx->dir, ctx->ino);
3695 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
3698 printf("%s", ctx->str ? ctx->str : "NULL");
3701 #ifdef EXT2_NO_64_TYPE
3702 printf("0x%x", ctx->num);
3704 printf("0x%llx", ctx->num);
3715 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
3716 struct problem_context *pctx, int first)
3718 ext2_filsys fs = ctx->fs;
3722 e2fsck_clear_progbar(ctx);
3723 for (cp = msg; *cp; cp++) {
3726 expand_at_expression(ctx, *cp, pctx, &first);
3727 } else if (cp[0] == '%' && cp[1] == 'I') {
3729 expand_inode_expression(*cp, pctx);
3730 } else if (cp[0] == '%' && cp[1] == 'D') {
3732 expand_dirent_expression(*cp, pctx);
3733 } else if ((cp[0] == '%')) {
3735 expand_percent_expression(fs, *cp, pctx);
3737 for (i=0; cp[i]; i++)
3738 if ((cp[i] == '@') || cp[i] == '%')
3740 printf("%.*s", i, cp);
3749 * region.c --- code which manages allocations within a region.
3753 region_addr_t start;
3755 struct region_el *next;
3758 struct region_struct {
3761 struct region_el *allocated;
3764 static region_t region_create(region_addr_t min, region_addr_t max)
3768 region = malloc(sizeof(struct region_struct));
3771 memset(region, 0, sizeof(struct region_struct));
3777 static void region_free(region_t region)
3779 struct region_el *r, *next;
3781 for (r = region->allocated; r; r = next) {
3785 memset(region, 0, sizeof(struct region_struct));
3789 static int region_allocate(region_t region, region_addr_t start, int n)
3791 struct region_el *r, *new_region, *prev, *next;
3795 if ((start < region->min) || (end > region->max))
3801 * Search through the linked list. If we find that it
3802 * conflicts witih something that's already allocated, return
3803 * 1; if we can find an existing region which we can grow, do
3804 * so. Otherwise, stop when we find the appropriate place
3805 * insert a new region element into the linked list.
3807 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
3808 if (((start >= r->start) && (start < r->end)) ||
3809 ((end > r->start) && (end <= r->end)) ||
3810 ((start <= r->start) && (end >= r->end)))
3812 if (end == r->start) {
3816 if (start == r->end) {
3817 if ((next = r->next)) {
3818 if (end > next->start)
3820 if (end == next->start) {
3822 r->next = next->next;
3830 if (start < r->start)
3834 * Insert a new region element structure into the linked list
3836 new_region = malloc(sizeof(struct region_el));
3839 new_region->start = start;
3840 new_region->end = start + n;
3841 new_region->next = r;
3843 prev->next = new_region;
3845 region->allocated = new_region;
3850 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
3852 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
3853 * and applies the following tests to each inode:
3855 * - The mode field of the inode must be legal.
3856 * - The size and block count fields of the inode are correct.
3857 * - A data block must not be used by another inode
3859 * Pass 1 also gathers the collects the following information:
3861 * - A bitmap of which inodes are in use. (inode_used_map)
3862 * - A bitmap of which inodes are directories. (inode_dir_map)
3863 * - A bitmap of which inodes are regular files. (inode_reg_map)
3864 * - A bitmap of which inodes have bad fields. (inode_bad_map)
3865 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
3866 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
3867 * - A bitmap of which blocks are in use. (block_found_map)
3868 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
3869 * - The data blocks of the directory inodes. (dir_map)
3871 * Pass 1 is designed to stash away enough information so that the
3872 * other passes should not need to read in the inode information
3873 * during the normal course of a filesystem check. (Althogh if an
3874 * inconsistency is detected, other passes may need to read in an
3877 * Note that pass 1B will be invoked if there are any duplicate blocks
3882 static int process_block(ext2_filsys fs, blk_t *blocknr,
3883 e2_blkcnt_t blockcnt, blk_t ref_blk,
3884 int ref_offset, void *priv_data);
3885 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3886 e2_blkcnt_t blockcnt, blk_t ref_blk,
3887 int ref_offset, void *priv_data);
3888 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3890 static void mark_table_blocks(e2fsck_t ctx);
3891 static void alloc_bb_map(e2fsck_t ctx);
3892 static void alloc_imagic_map(e2fsck_t ctx);
3893 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3894 static void handle_fs_bad_blocks(e2fsck_t ctx);
3895 static void process_inodes(e2fsck_t ctx, char *block_buf);
3896 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
3897 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3898 dgrp_t group, void * priv_data);
3899 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3900 char *block_buf, int adjust_sign);
3901 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3903 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3904 struct ext2_inode * inode, int bufsize,
3907 struct process_block_struct_1 {
3909 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
3910 fragmented:1, compressed:1, bbcheck:1;
3913 e2_blkcnt_t last_block;
3914 int num_illegal_blocks;
3915 blk_t previous_block;
3916 struct ext2_inode *inode;
3917 struct problem_context *pctx;
3918 ext2fs_block_bitmap fs_meta_blocks;
3922 struct process_inode_block {
3924 struct ext2_inode inode;
3927 struct scan_callback_struct {
3933 * For the inodes to process list.
3935 static struct process_inode_block *inodes_to_process;
3936 static int process_inode_count;
3938 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3939 EXT2_MIN_BLOCK_LOG_SIZE + 1];
3942 * Free all memory allocated by pass1 in preparation for restarting
3945 static void unwind_pass1(void)
3947 ext2fs_free_mem(&inodes_to_process);
3951 * Check to make sure a device inode is real. Returns 1 if the device
3952 * checks out, 0 if not.
3954 * Note: this routine is now also used to check FIFO's and Sockets,
3955 * since they have the same requirement; the i_block fields should be
3959 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3964 * If i_blocks is non-zero, or the index flag is set, then
3965 * this is a bogus device/fifo/socket
3967 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3968 (inode->i_flags & EXT2_INDEX_FL))
3972 * We should be able to do the test below all the time, but
3973 * because the kernel doesn't forcibly clear the device
3974 * inode's additional i_block fields, there are some rare
3975 * occasions when a legitimate device inode will have non-zero
3976 * additional i_block fields. So for now, we only complain
3977 * when the immutable flag is set, which should never happen
3978 * for devices. (And that's when the problem is caused, since
3979 * you can't set or clear immutable flags for devices.) Once
3980 * the kernel has been fixed we can change this...
3982 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
3983 for (i=4; i < EXT2_N_BLOCKS; i++)
3984 if (inode->i_block[i])
3991 * Check to make sure a symlink inode is real. Returns 1 if the symlink
3992 * checks out, 0 if not.
3995 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
4001 if ((inode->i_size_high || inode->i_size == 0) ||
4002 (inode->i_flags & EXT2_INDEX_FL))
4005 blocks = ext2fs_inode_data_blocks(fs, inode);
4007 if ((inode->i_size >= fs->blocksize) ||
4008 (blocks != fs->blocksize >> 9) ||
4009 (inode->i_block[0] < fs->super->s_first_data_block) ||
4010 (inode->i_block[0] >= fs->super->s_blocks_count))
4013 for (i = 1; i < EXT2_N_BLOCKS; i++)
4014 if (inode->i_block[i])
4017 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
4020 len = strnlen(buf, fs->blocksize);
4021 if (len == fs->blocksize)
4024 if (inode->i_size >= sizeof(inode->i_block))
4027 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
4028 if (len == sizeof(inode->i_block))
4031 if (len != inode->i_size)
4037 * If the immutable (or append-only) flag is set on the inode, offer
4040 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
4041 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
4043 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
4046 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
4049 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
4050 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4054 * If device, fifo or socket, check size is zero -- if not offer to
4057 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
4059 struct ext2_inode *inode = pctx->inode;
4061 if ((inode->i_size == 0) && (inode->i_size_high == 0))
4064 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
4068 inode->i_size_high = 0;
4069 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4072 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
4074 struct ext2_super_block *sb = ctx->fs->super;
4075 struct ext2_inode_large *inode;
4076 struct ext2_ext_attr_entry *entry;
4078 int storage_size, remain, offs;
4081 inode = (struct ext2_inode_large *) pctx->inode;
4082 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
4083 inode->i_extra_isize;
4084 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4085 inode->i_extra_isize + sizeof(__u32);
4086 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
4087 entry = (struct ext2_ext_attr_entry *) start;
4089 /* scan all entry's headers first */
4091 /* take finish entry 0UL into account */
4092 remain = storage_size - sizeof(__u32);
4095 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
4097 /* header eats this space */
4098 remain -= sizeof(struct ext2_ext_attr_entry);
4100 /* is attribute name valid? */
4101 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
4102 pctx->num = entry->e_name_len;
4103 problem = PR_1_ATTR_NAME_LEN;
4107 /* attribute len eats this space */
4108 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
4110 /* check value size */
4111 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
4112 pctx->num = entry->e_value_size;
4113 problem = PR_1_ATTR_VALUE_SIZE;
4117 /* check value placement */
4118 if (entry->e_value_offs +
4119 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
4120 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
4121 pctx->num = entry->e_value_offs;
4122 problem = PR_1_ATTR_VALUE_OFFSET;
4126 /* e_value_block must be 0 in inode's ea */
4127 if (entry->e_value_block != 0) {
4128 pctx->num = entry->e_value_block;
4129 problem = PR_1_ATTR_VALUE_BLOCK;
4133 /* e_hash must be 0 in inode's ea */
4134 if (entry->e_hash != 0) {
4135 pctx->num = entry->e_hash;
4136 problem = PR_1_ATTR_HASH;
4140 remain -= entry->e_value_size;
4141 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
4143 entry = EXT2_EXT_ATTR_NEXT(entry);
4147 * it seems like a corruption. it's very unlikely we could repair
4148 * EA(s) in automatic fashion -bzzz
4150 if (problem == 0 || !fix_problem(ctx, problem, pctx))
4153 /* simple remove all possible EA(s) */
4154 *((__u32 *)start) = 0UL;
4155 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
4156 EXT2_INODE_SIZE(sb), "pass1");
4159 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
4161 struct ext2_super_block *sb = ctx->fs->super;
4162 struct ext2_inode_large *inode;
4166 inode = (struct ext2_inode_large *) pctx->inode;
4167 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
4168 /* this isn't large inode. so, nothing to check */
4172 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
4173 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
4174 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
4176 * For now we will allow i_extra_isize to be 0, but really
4177 * implementations should never allow i_extra_isize to be 0
4179 if (inode->i_extra_isize &&
4180 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
4181 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
4183 inode->i_extra_isize = min;
4184 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
4185 EXT2_INODE_SIZE(sb), "pass1");
4189 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4190 inode->i_extra_isize);
4191 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
4192 /* it seems inode has an extended attribute(s) in body */
4193 check_ea_in_inode(ctx, pctx);
4197 static void e2fsck_pass1(e2fsck_t ctx)
4201 ext2_filsys fs = ctx->fs;
4203 struct ext2_inode *inode;
4204 ext2_inode_scan scan;
4206 unsigned char frag, fsize;
4207 struct problem_context pctx;
4208 struct scan_callback_struct scan_struct;
4209 struct ext2_super_block *sb = ctx->fs->super;
4211 int busted_fs_time = 0;
4214 clear_problem_context(&pctx);
4216 if (!(ctx->options & E2F_OPT_PREEN))
4217 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
4219 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4220 !(ctx->options & E2F_OPT_NO)) {
4221 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
4222 ctx->dirs_to_hash = 0;
4227 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
4229 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
4230 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
4231 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
4232 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
4233 max_sizes = (max_sizes * (1UL << i)) - 1;
4234 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
4238 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
4241 * Allocate bitmaps structures
4243 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
4244 &ctx->inode_used_map);
4247 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4248 ctx->flags |= E2F_FLAG_ABORT;
4251 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4252 _("directory inode map"), &ctx->inode_dir_map);
4255 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4256 ctx->flags |= E2F_FLAG_ABORT;
4259 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4260 _("regular file inode map"), &ctx->inode_reg_map);
4263 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4264 ctx->flags |= E2F_FLAG_ABORT;
4267 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
4268 &ctx->block_found_map);
4271 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4272 ctx->flags |= E2F_FLAG_ABORT;
4275 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
4276 &ctx->inode_link_info);
4278 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
4279 ctx->flags |= E2F_FLAG_ABORT;
4282 inode_size = EXT2_INODE_SIZE(fs->super);
4283 inode = (struct ext2_inode *)
4284 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
4286 inodes_to_process = (struct process_inode_block *)
4287 e2fsck_allocate_memory(ctx,
4288 (ctx->process_inode_size *
4289 sizeof(struct process_inode_block)),
4290 "array of inodes to process");
4291 process_inode_count = 0;
4293 pctx.errcode = ext2fs_init_dblist(fs, 0);
4295 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
4296 ctx->flags |= E2F_FLAG_ABORT;
4301 * If the last orphan field is set, clear it, since the pass1
4302 * processing will automatically find and clear the orphans.
4303 * In the future, we may want to try using the last_orphan
4304 * linked list ourselves, but for now, we clear it so that the
4305 * ext3 mount code won't get confused.
4307 if (!(ctx->options & E2F_OPT_READONLY)) {
4308 if (fs->super->s_last_orphan) {
4309 fs->super->s_last_orphan = 0;
4310 ext2fs_mark_super_dirty(fs);
4314 mark_table_blocks(ctx);
4315 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
4316 "block interate buffer");
4317 e2fsck_use_inode_shortcuts(ctx, 1);
4318 ehandler_operation(_("doing inode scan"));
4319 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4322 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4323 ctx->flags |= E2F_FLAG_ABORT;
4326 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
4327 ctx->stashed_inode = inode;
4328 scan_struct.ctx = ctx;
4329 scan_struct.block_buf = block_buf;
4330 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
4332 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
4334 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
4335 (fs->super->s_mtime < fs->super->s_inodes_count))
4339 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
4341 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4343 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
4344 if (!ctx->inode_bb_map)
4346 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
4347 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4351 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4352 ctx->flags |= E2F_FLAG_ABORT;
4359 ctx->stashed_ino = ino;
4360 if (inode->i_links_count) {
4361 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
4362 ino, inode->i_links_count);
4364 pctx.num = inode->i_links_count;
4365 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
4366 ctx->flags |= E2F_FLAG_ABORT;
4370 if (ino == EXT2_BAD_INO) {
4371 struct process_block_struct_1 pb;
4373 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
4374 &pb.fs_meta_blocks);
4377 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4378 ctx->flags |= E2F_FLAG_ABORT;
4381 pb.ino = EXT2_BAD_INO;
4382 pb.num_blocks = pb.last_block = 0;
4383 pb.num_illegal_blocks = 0;
4384 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
4385 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
4389 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
4390 block_buf, process_bad_block, &pb);
4391 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
4393 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
4394 ctx->flags |= E2F_FLAG_ABORT;
4398 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
4399 ctx->flags |= E2F_FLAG_ABORT;
4402 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4403 clear_problem_context(&pctx);
4405 } else if (ino == EXT2_ROOT_INO) {
4407 * Make sure the root inode is a directory; if
4408 * not, offer to clear it. It will be
4409 * regnerated in pass #3.
4411 if (!LINUX_S_ISDIR(inode->i_mode)) {
4412 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
4413 inode->i_dtime = time(0);
4414 inode->i_links_count = 0;
4415 ext2fs_icount_store(ctx->inode_link_info,
4417 e2fsck_write_inode(ctx, ino, inode,
4423 * If dtime is set, offer to clear it. mke2fs
4424 * version 0.2b created filesystems with the
4425 * dtime field set for the root and lost+found
4426 * directories. We won't worry about
4427 * /lost+found, since that can be regenerated
4428 * easily. But we will fix the root directory
4429 * as a special case.
4431 if (inode->i_dtime && inode->i_links_count) {
4432 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
4434 e2fsck_write_inode(ctx, ino, inode,
4438 } else if (ino == EXT2_JOURNAL_INO) {
4439 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4440 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
4441 if (!LINUX_S_ISREG(inode->i_mode) &&
4442 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
4444 inode->i_mode = LINUX_S_IFREG;
4445 e2fsck_write_inode(ctx, ino, inode,
4448 check_blocks(ctx, &pctx, block_buf);
4451 if ((inode->i_links_count || inode->i_blocks ||
4452 inode->i_blocks || inode->i_block[0]) &&
4453 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
4455 memset(inode, 0, inode_size);
4456 ext2fs_icount_store(ctx->inode_link_info,
4458 e2fsck_write_inode_full(ctx, ino, inode,
4459 inode_size, "pass1");
4461 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
4464 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4465 if (ino == EXT2_BOOT_LOADER_INO) {
4466 if (LINUX_S_ISDIR(inode->i_mode))
4467 problem = PR_1_RESERVED_BAD_MODE;
4468 } else if (ino == EXT2_RESIZE_INO) {
4469 if (inode->i_mode &&
4470 !LINUX_S_ISREG(inode->i_mode))
4471 problem = PR_1_RESERVED_BAD_MODE;
4473 if (inode->i_mode != 0)
4474 problem = PR_1_RESERVED_BAD_MODE;
4477 if (fix_problem(ctx, problem, &pctx)) {
4479 e2fsck_write_inode(ctx, ino, inode,
4483 check_blocks(ctx, &pctx, block_buf);
4487 * Check for inodes who might have been part of the
4488 * orphaned list linked list. They should have gotten
4489 * dealt with by now, unless the list had somehow been
4492 * FIXME: In the future, inodes which are still in use
4493 * (and which are therefore) pending truncation should
4494 * be handled specially. Right now we just clear the
4495 * dtime field, and the normal e2fsck handling of
4496 * inodes where i_size and the inode blocks are
4497 * inconsistent is to fix i_size, instead of releasing
4498 * the extra blocks. This won't catch the inodes that
4499 * was at the end of the orphan list, but it's better
4500 * than nothing. The right answer is that there
4501 * shouldn't be any bugs in the orphan list handling. :-)
4503 if (inode->i_dtime && !busted_fs_time &&
4504 inode->i_dtime < ctx->fs->super->s_inodes_count) {
4505 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
4506 inode->i_dtime = inode->i_links_count ?
4508 e2fsck_write_inode(ctx, ino, inode,
4514 * This code assumes that deleted inodes have
4515 * i_links_count set to 0.
4517 if (!inode->i_links_count) {
4518 if (!inode->i_dtime && inode->i_mode) {
4519 if (fix_problem(ctx,
4520 PR_1_ZERO_DTIME, &pctx)) {
4521 inode->i_dtime = time(0);
4522 e2fsck_write_inode(ctx, ino, inode,
4529 * n.b. 0.3c ext2fs code didn't clear i_links_count for
4530 * deleted files. Oops.
4532 * Since all new ext2 implementations get this right,
4533 * we now assume that the case of non-zero
4534 * i_links_count and non-zero dtime means that we
4535 * should keep the file, not delete it.
4538 if (inode->i_dtime) {
4539 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
4541 e2fsck_write_inode(ctx, ino, inode, "pass1");
4545 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4546 switch (fs->super->s_creator_os) {
4548 frag = inode->osd2.linux2.l_i_frag;
4549 fsize = inode->osd2.linux2.l_i_fsize;
4552 frag = inode->osd2.hurd2.h_i_frag;
4553 fsize = inode->osd2.hurd2.h_i_fsize;
4556 frag = inode->osd2.masix2.m_i_frag;
4557 fsize = inode->osd2.masix2.m_i_fsize;
4563 if (inode->i_faddr || frag || fsize ||
4564 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
4565 mark_inode_bad(ctx, ino);
4566 if (inode->i_flags & EXT2_IMAGIC_FL) {
4568 if (!ctx->inode_imagic_map)
4569 alloc_imagic_map(ctx);
4570 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
4573 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
4574 inode->i_flags &= ~EXT2_IMAGIC_FL;
4575 e2fsck_write_inode(ctx, ino,
4581 check_inode_extra_space(ctx, &pctx);
4583 if (LINUX_S_ISDIR(inode->i_mode)) {
4584 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
4585 e2fsck_add_dir_info(ctx, ino, 0);
4586 ctx->fs_directory_count++;
4587 } else if (LINUX_S_ISREG (inode->i_mode)) {
4588 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
4589 ctx->fs_regular_count++;
4590 } else if (LINUX_S_ISCHR (inode->i_mode) &&
4591 e2fsck_pass1_check_device_inode(fs, inode)) {
4592 check_immutable(ctx, &pctx);
4593 check_size(ctx, &pctx);
4594 ctx->fs_chardev_count++;
4595 } else if (LINUX_S_ISBLK (inode->i_mode) &&
4596 e2fsck_pass1_check_device_inode(fs, inode)) {
4597 check_immutable(ctx, &pctx);
4598 check_size(ctx, &pctx);
4599 ctx->fs_blockdev_count++;
4600 } else if (LINUX_S_ISLNK (inode->i_mode) &&
4601 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
4602 check_immutable(ctx, &pctx);
4603 ctx->fs_symlinks_count++;
4604 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
4605 ctx->fs_fast_symlinks_count++;
4606 check_blocks(ctx, &pctx, block_buf);
4610 else if (LINUX_S_ISFIFO (inode->i_mode) &&
4611 e2fsck_pass1_check_device_inode(fs, inode)) {
4612 check_immutable(ctx, &pctx);
4613 check_size(ctx, &pctx);
4614 ctx->fs_fifo_count++;
4615 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
4616 e2fsck_pass1_check_device_inode(fs, inode)) {
4617 check_immutable(ctx, &pctx);
4618 check_size(ctx, &pctx);
4619 ctx->fs_sockets_count++;
4621 mark_inode_bad(ctx, ino);
4622 if (inode->i_block[EXT2_IND_BLOCK])
4623 ctx->fs_ind_count++;
4624 if (inode->i_block[EXT2_DIND_BLOCK])
4625 ctx->fs_dind_count++;
4626 if (inode->i_block[EXT2_TIND_BLOCK])
4627 ctx->fs_tind_count++;
4628 if (inode->i_block[EXT2_IND_BLOCK] ||
4629 inode->i_block[EXT2_DIND_BLOCK] ||
4630 inode->i_block[EXT2_TIND_BLOCK] ||
4631 inode->i_file_acl) {
4632 inodes_to_process[process_inode_count].ino = ino;
4633 inodes_to_process[process_inode_count].inode = *inode;
4634 process_inode_count++;
4636 check_blocks(ctx, &pctx, block_buf);
4638 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4641 if (process_inode_count >= ctx->process_inode_size) {
4642 process_inodes(ctx, block_buf);
4644 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4648 process_inodes(ctx, block_buf);
4649 ext2fs_close_inode_scan(scan);
4650 ehandler_operation(0);
4653 * If any extended attribute blocks' reference counts need to
4654 * be adjusted, either up (ctx->refcount_extra), or down
4655 * (ctx->refcount), then fix them.
4657 if (ctx->refcount) {
4658 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
4659 ea_refcount_free(ctx->refcount);
4662 if (ctx->refcount_extra) {
4663 adjust_extattr_refcount(ctx, ctx->refcount_extra,
4665 ea_refcount_free(ctx->refcount_extra);
4666 ctx->refcount_extra = 0;
4669 if (ctx->invalid_bitmaps)
4670 handle_fs_bad_blocks(ctx);
4672 /* We don't need the block_ea_map any more */
4673 ext2fs_free_block_bitmap(ctx->block_ea_map);
4674 ctx->block_ea_map = 0;
4676 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
4677 ext2fs_block_bitmap save_bmap;
4679 save_bmap = fs->block_map;
4680 fs->block_map = ctx->block_found_map;
4681 clear_problem_context(&pctx);
4682 pctx.errcode = ext2fs_create_resize_inode(fs);
4684 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
4685 /* Should never get here */
4686 ctx->flags |= E2F_FLAG_ABORT;
4689 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
4691 inode->i_mtime = time(0);
4692 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
4694 fs->block_map = save_bmap;
4695 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
4698 if (ctx->flags & E2F_FLAG_RESTART) {
4700 * Only the master copy of the superblock and block
4701 * group descriptors are going to be written during a
4702 * restart, so set the superblock to be used to be the
4703 * master superblock.
4705 ctx->use_superblock = 0;
4710 if (ctx->block_dup_map) {
4711 if (ctx->options & E2F_OPT_PREEN) {
4712 clear_problem_context(&pctx);
4713 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
4715 e2fsck_pass1_dupblocks(ctx, block_buf);
4717 ext2fs_free_mem(&inodes_to_process);
4719 e2fsck_use_inode_shortcuts(ctx, 0);
4721 ext2fs_free_mem(&block_buf);
4722 ext2fs_free_mem(&inode);
4727 * When the inode_scan routines call this callback at the end of the
4728 * glock group, call process_inodes.
4730 static errcode_t scan_callback(ext2_filsys fs,
4731 ext2_inode_scan scan FSCK_ATTR((unused)),
4732 dgrp_t group, void * priv_data)
4734 struct scan_callback_struct *scan_struct;
4737 scan_struct = (struct scan_callback_struct *) priv_data;
4738 ctx = scan_struct->ctx;
4740 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
4743 if ((ctx->progress)(ctx, 1, group+1,
4744 ctx->fs->group_desc_count))
4745 return EXT2_ET_CANCEL_REQUESTED;
4751 * Process the inodes in the "inodes to process" list.
4753 static void process_inodes(e2fsck_t ctx, char *block_buf)
4756 struct ext2_inode *old_stashed_inode;
4757 ext2_ino_t old_stashed_ino;
4758 const char *old_operation;
4760 struct problem_context pctx;
4762 /* begin process_inodes */
4763 if (process_inode_count == 0)
4765 old_operation = ehandler_operation(0);
4766 old_stashed_inode = ctx->stashed_inode;
4767 old_stashed_ino = ctx->stashed_ino;
4768 qsort(inodes_to_process, process_inode_count,
4769 sizeof(struct process_inode_block), process_inode_cmp);
4770 clear_problem_context(&pctx);
4771 for (i=0; i < process_inode_count; i++) {
4772 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
4773 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
4774 sprintf(buf, _("reading indirect blocks of inode %u"),
4776 ehandler_operation(buf);
4777 check_blocks(ctx, &pctx, block_buf);
4778 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4781 ctx->stashed_inode = old_stashed_inode;
4782 ctx->stashed_ino = old_stashed_ino;
4783 process_inode_count = 0;
4784 /* end process inodes */
4786 ehandler_operation(old_operation);
4789 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
4791 const struct process_inode_block *ib_a =
4792 (const struct process_inode_block *) a;
4793 const struct process_inode_block *ib_b =
4794 (const struct process_inode_block *) b;
4797 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
4798 ib_b->inode.i_block[EXT2_IND_BLOCK]);
4800 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
4805 * Mark an inode as being bad in some what
4807 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
4809 struct problem_context pctx;
4811 if (!ctx->inode_bad_map) {
4812 clear_problem_context(&pctx);
4814 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4815 _("bad inode map"), &ctx->inode_bad_map);
4818 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4819 /* Should never get here */
4820 ctx->flags |= E2F_FLAG_ABORT;
4824 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
4829 * This procedure will allocate the inode "bb" (badblock) map table
4831 static void alloc_bb_map(e2fsck_t ctx)
4833 struct problem_context pctx;
4835 clear_problem_context(&pctx);
4836 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4837 _("inode in bad block map"),
4838 &ctx->inode_bb_map);
4841 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4842 /* Should never get here */
4843 ctx->flags |= E2F_FLAG_ABORT;
4849 * This procedure will allocate the inode imagic table
4851 static void alloc_imagic_map(e2fsck_t ctx)
4853 struct problem_context pctx;
4855 clear_problem_context(&pctx);
4856 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4857 _("imagic inode map"),
4858 &ctx->inode_imagic_map);
4861 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4862 /* Should never get here */
4863 ctx->flags |= E2F_FLAG_ABORT;
4869 * Marks a block as in use, setting the dup_map if it's been set
4870 * already. Called by process_block and process_bad_block.
4872 * WARNING: Assumes checks have already been done to make sure block
4873 * is valid. This is true in both process_block and process_bad_block.
4875 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
4877 struct problem_context pctx;
4879 clear_problem_context(&pctx);
4881 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4882 if (!ctx->block_dup_map) {
4883 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4884 _("multiply claimed block map"),
4885 &ctx->block_dup_map);
4888 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4890 /* Should never get here */
4891 ctx->flags |= E2F_FLAG_ABORT;
4895 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4897 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4902 * Adjust the extended attribute block's reference counts at the end
4903 * of pass 1, either by subtracting out references for EA blocks that
4904 * are still referenced in ctx->refcount, or by adding references for
4905 * EA blocks that had extra references as accounted for in
4906 * ctx->refcount_extra.
4908 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4909 char *block_buf, int adjust_sign)
4911 struct ext2_ext_attr_header *header;
4912 struct problem_context pctx;
4913 ext2_filsys fs = ctx->fs;
4918 clear_problem_context(&pctx);
4920 ea_refcount_intr_begin(refcount);
4922 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4925 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4927 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4930 header = (struct ext2_ext_attr_header *) block_buf;
4931 pctx.blkcount = header->h_refcount;
4932 should_be = header->h_refcount + adjust_sign * count;
4933 pctx.num = should_be;
4934 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4935 header->h_refcount = should_be;
4936 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4939 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4947 * Handle processing the extended attribute blocks
4949 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4952 ext2_filsys fs = ctx->fs;
4953 ext2_ino_t ino = pctx->ino;
4954 struct ext2_inode *inode = pctx->inode;
4957 struct ext2_ext_attr_header *header;
4958 struct ext2_ext_attr_entry *entry;
4962 blk = inode->i_file_acl;
4967 * If the Extended attribute flag isn't set, then a non-zero
4968 * file acl means that the inode is corrupted.
4970 * Or if the extended attribute block is an invalid block,
4971 * then the inode is also corrupted.
4973 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
4974 (blk < fs->super->s_first_data_block) ||
4975 (blk >= fs->super->s_blocks_count)) {
4976 mark_inode_bad(ctx, ino);
4980 /* If ea bitmap hasn't been allocated, create it */
4981 if (!ctx->block_ea_map) {
4982 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
4983 _("ext attr block map"),
4984 &ctx->block_ea_map);
4985 if (pctx->errcode) {
4987 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
4988 ctx->flags |= E2F_FLAG_ABORT;
4993 /* Create the EA refcount structure if necessary */
4994 if (!ctx->refcount) {
4995 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
4996 if (pctx->errcode) {
4998 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4999 ctx->flags |= E2F_FLAG_ABORT;
5004 /* Have we seen this EA block before? */
5005 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
5006 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
5008 /* Ooops, this EA was referenced more than it stated */
5009 if (!ctx->refcount_extra) {
5010 pctx->errcode = ea_refcount_create(0,
5011 &ctx->refcount_extra);
5012 if (pctx->errcode) {
5014 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5015 ctx->flags |= E2F_FLAG_ABORT;
5019 ea_refcount_increment(ctx->refcount_extra, blk, 0);
5024 * OK, we haven't seen this EA block yet. So we need to
5028 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5029 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
5031 header = (struct ext2_ext_attr_header *) block_buf;
5032 pctx->blk = inode->i_file_acl;
5033 if (((ctx->ext_attr_ver == 1) &&
5034 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
5035 ((ctx->ext_attr_ver == 2) &&
5036 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
5037 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
5041 if (header->h_blocks != 1) {
5042 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
5046 region = region_create(0, fs->blocksize);
5048 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
5049 ctx->flags |= E2F_FLAG_ABORT;
5052 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
5053 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5057 entry = (struct ext2_ext_attr_entry *)(header+1);
5058 end = block_buf + fs->blocksize;
5059 while ((char *)entry < end && *(__u32 *)entry) {
5060 if (region_allocate(region, (char *)entry - (char *)header,
5061 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
5062 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5065 if ((ctx->ext_attr_ver == 1 &&
5066 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
5067 (ctx->ext_attr_ver == 2 &&
5068 entry->e_name_index == 0)) {
5069 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
5072 if (entry->e_value_block != 0) {
5073 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
5076 if (entry->e_value_size &&
5077 region_allocate(region, entry->e_value_offs,
5078 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
5079 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5082 entry = EXT2_EXT_ATTR_NEXT(entry);
5084 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
5085 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5088 region_free(region);
5090 count = header->h_refcount - 1;
5092 ea_refcount_store(ctx->refcount, blk, count);
5093 mark_block_used(ctx, blk);
5094 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
5099 inode->i_file_acl = 0;
5100 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
5104 /* Returns 1 if bad htree, 0 if OK */
5105 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
5106 ext2_ino_t ino FSCK_ATTR((unused)),
5107 struct ext2_inode *inode,
5110 struct ext2_dx_root_info *root;
5111 ext2_filsys fs = ctx->fs;
5115 if ((!LINUX_S_ISDIR(inode->i_mode) &&
5116 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
5117 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
5118 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
5121 blk = inode->i_block[0];
5123 (blk < fs->super->s_first_data_block) ||
5124 (blk >= fs->super->s_blocks_count)) &&
5125 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5128 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
5129 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5132 /* XXX should check that beginning matches a directory */
5133 root = (struct ext2_dx_root_info *) (block_buf + 24);
5135 if ((root->reserved_zero || root->info_length < 8) &&
5136 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5139 pctx->num = root->hash_version;
5140 if ((root->hash_version != EXT2_HASH_LEGACY) &&
5141 (root->hash_version != EXT2_HASH_HALF_MD4) &&
5142 (root->hash_version != EXT2_HASH_TEA) &&
5143 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
5146 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
5147 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
5150 pctx->num = root->indirect_levels;
5151 if ((root->indirect_levels > 1) &&
5152 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
5159 * This subroutine is called on each inode to account for all of the
5160 * blocks used by that inode.
5162 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
5165 ext2_filsys fs = ctx->fs;
5166 struct process_block_struct_1 pb;
5167 ext2_ino_t ino = pctx->ino;
5168 struct ext2_inode *inode = pctx->inode;
5170 int dirty_inode = 0;
5176 pb.num_illegal_blocks = 0;
5177 pb.suppress = 0; pb.clear = 0;
5180 pb.previous_block = 0;
5181 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
5182 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
5183 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
5190 if (inode->i_flags & EXT2_COMPRBLK_FL) {
5191 if (fs->super->s_feature_incompat &
5192 EXT2_FEATURE_INCOMPAT_COMPRESSION)
5195 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
5196 inode->i_flags &= ~EXT2_COMPRBLK_FL;
5202 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
5205 if (ext2fs_inode_has_valid_blocks(inode))
5206 pctx->errcode = ext2fs_block_iterate2(fs, ino,
5207 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
5208 block_buf, process_block, &pb);
5209 end_problem_latch(ctx, PR_LATCH_BLOCK);
5210 end_problem_latch(ctx, PR_LATCH_TOOBIG);
5211 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5214 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
5216 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
5217 ctx->fs_fragmented++;
5220 inode->i_links_count = 0;
5221 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5222 inode->i_dtime = time(0);
5224 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5225 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5226 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5228 * The inode was probably partially accounted for
5229 * before processing was aborted, so we need to
5230 * restart the pass 1 scan.
5232 ctx->flags |= E2F_FLAG_RESTART;
5236 if (inode->i_flags & EXT2_INDEX_FL) {
5237 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
5238 inode->i_flags &= ~EXT2_INDEX_FL;
5242 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
5246 if (ctx->dirs_to_hash && pb.is_dir &&
5247 !(inode->i_flags & EXT2_INDEX_FL) &&
5248 ((inode->i_size / fs->blocksize) >= 3))
5249 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
5251 if (!pb.num_blocks && pb.is_dir) {
5252 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
5253 inode->i_links_count = 0;
5254 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5255 inode->i_dtime = time(0);
5257 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5258 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5259 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5260 ctx->fs_directory_count--;
5265 pb.num_blocks *= (fs->blocksize / 512);
5268 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
5269 if (nblock > (pb.last_block + 1))
5271 else if (nblock < (pb.last_block + 1)) {
5272 if (((pb.last_block + 1) - nblock) >
5273 fs->super->s_prealloc_dir_blocks)
5277 size = EXT2_I_SIZE(inode);
5278 if ((pb.last_block >= 0) &&
5279 (size < (__u64) pb.last_block * fs->blocksize))
5281 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
5284 /* i_size for symlinks is checked elsewhere */
5285 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
5286 pctx->num = (pb.last_block+1) * fs->blocksize;
5287 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
5288 inode->i_size = pctx->num;
5289 if (!LINUX_S_ISDIR(inode->i_mode))
5290 inode->i_size_high = pctx->num >> 32;
5295 if (LINUX_S_ISREG(inode->i_mode) &&
5296 (inode->i_size_high || inode->i_size & 0x80000000UL))
5298 if (pb.num_blocks != inode->i_blocks) {
5299 pctx->num = pb.num_blocks;
5300 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
5301 inode->i_blocks = pb.num_blocks;
5308 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
5313 * This is a helper function for check_blocks().
5315 static int process_block(ext2_filsys fs,
5317 e2_blkcnt_t blockcnt,
5318 blk_t ref_block FSCK_ATTR((unused)),
5319 int ref_offset FSCK_ATTR((unused)),
5322 struct process_block_struct_1 *p;
5323 struct problem_context *pctx;
5324 blk_t blk = *block_nr;
5329 p = (struct process_block_struct_1 *) priv_data;
5333 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
5334 /* todo: Check that the comprblk_fl is high, that the
5335 blkaddr pattern looks right (all non-holes up to
5336 first EXT2FS_COMPRESSED_BLKADDR, then all
5337 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
5338 that the feature_incompat bit is high, and that the
5339 inode is a regular file. If we're doing a "full
5340 check" (a concept introduced to e2fsck by e2compr,
5341 meaning that we look at data blocks as well as
5342 metadata) then call some library routine that
5343 checks the compressed data. I'll have to think
5344 about this, because one particularly important
5345 problem to be able to fix is to recalculate the
5346 cluster size if necessary. I think that perhaps
5347 we'd better do most/all e2compr-specific checks
5348 separately, after the non-e2compr checks. If not
5349 doing a full check, it may be useful to test that
5350 the personality is linux; e.g. if it isn't then
5351 perhaps this really is just an illegal block. */
5356 if (p->is_dir == 0) {
5358 * Should never happen, since only directories
5359 * get called with BLOCK_FLAG_HOLE
5362 printf("process_block() called with blk == 0, "
5363 "blockcnt=%d, inode %lu???\n",
5370 if (blockcnt * fs->blocksize < p->inode->i_size) {
5377 * Simplistic fragmentation check. We merely require that the
5378 * file be contiguous. (Which can never be true for really
5379 * big files that are greater than a block group.)
5381 if (!HOLE_BLKADDR(p->previous_block)) {
5382 if (p->previous_block+1 != blk)
5385 p->previous_block = blk;
5387 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
5388 problem = PR_1_TOOBIG_DIR;
5389 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
5390 problem = PR_1_TOOBIG_REG;
5391 if (!p->is_dir && !p->is_reg && blockcnt > 0)
5392 problem = PR_1_TOOBIG_SYMLINK;
5394 if (blk < fs->super->s_first_data_block ||
5395 blk >= fs->super->s_blocks_count)
5396 problem = PR_1_ILLEGAL_BLOCK_NUM;
5399 p->num_illegal_blocks++;
5400 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
5401 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
5405 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
5407 set_latch_flags(PR_LATCH_BLOCK,
5412 pctx->blkcount = blockcnt;
5413 if (fix_problem(ctx, problem, pctx)) {
5414 blk = *block_nr = 0;
5415 ret_code = BLOCK_CHANGED;
5421 if (p->ino == EXT2_RESIZE_INO) {
5423 * The resize inode has already be sanity checked
5424 * during pass #0 (the superblock checks). All we
5425 * have to do is mark the double indirect block as
5426 * being in use; all of the other blocks are handled
5427 * by mark_table_blocks()).
5429 if (blockcnt == BLOCK_COUNT_DIND)
5430 mark_block_used(ctx, blk);
5432 mark_block_used(ctx, blk);
5435 p->last_block = blockcnt;
5437 if (p->is_dir && (blockcnt >= 0)) {
5438 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
5440 if (pctx->errcode) {
5442 pctx->num = blockcnt;
5443 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
5444 /* Should never get here */
5445 ctx->flags |= E2F_FLAG_ABORT;
5452 static int process_bad_block(ext2_filsys fs,
5454 e2_blkcnt_t blockcnt,
5455 blk_t ref_block FSCK_ATTR((unused)),
5456 int ref_offset FSCK_ATTR((unused)),
5459 struct process_block_struct_1 *p;
5460 blk_t blk = *block_nr;
5463 struct problem_context *pctx;
5467 * Note: This function processes blocks for the bad blocks
5468 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
5474 p = (struct process_block_struct_1 *) priv_data;
5478 pctx->ino = EXT2_BAD_INO;
5480 pctx->blkcount = blockcnt;
5482 if ((blk < fs->super->s_first_data_block) ||
5483 (blk >= fs->super->s_blocks_count)) {
5484 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
5486 return BLOCK_CHANGED;
5492 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
5494 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
5496 return BLOCK_CHANGED;
5498 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
5501 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
5504 return BLOCK_CHANGED;
5506 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5509 mark_block_used(ctx, blk);
5513 ctx->fs_badblocks_count++;
5515 * If the block is not used, then mark it as used and return.
5516 * If it is already marked as found, this must mean that
5517 * there's an overlap between the filesystem table blocks
5518 * (bitmaps and inode table) and the bad block list.
5520 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
5521 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
5525 * Try to find the where the filesystem block was used...
5527 first_block = fs->super->s_first_data_block;
5529 for (i = 0; i < fs->group_desc_count; i++ ) {
5532 if (!ext2fs_bg_has_super(fs, i))
5534 if (blk == first_block) {
5536 if (fix_problem(ctx,
5537 PR_1_BAD_PRIMARY_SUPERBLOCK,
5540 return BLOCK_CHANGED;
5544 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
5547 if ((blk > first_block) &&
5548 (blk <= first_block + fs->desc_blocks)) {
5550 pctx->blk = *block_nr;
5551 if (fix_problem(ctx,
5552 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
5554 return BLOCK_CHANGED;
5558 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
5562 if (blk == fs->group_desc[i].bg_block_bitmap) {
5563 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
5564 ctx->invalid_block_bitmap_flag[i]++;
5565 ctx->invalid_bitmaps++;
5569 if (blk == fs->group_desc[i].bg_inode_bitmap) {
5570 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
5571 ctx->invalid_inode_bitmap_flag[i]++;
5572 ctx->invalid_bitmaps++;
5576 if ((blk >= fs->group_desc[i].bg_inode_table) &&
5577 (blk < (fs->group_desc[i].bg_inode_table +
5578 fs->inode_blocks_per_group))) {
5580 * If there are bad blocks in the inode table,
5581 * the inode scan code will try to do
5582 * something reasonable automatically.
5586 first_block += fs->super->s_blocks_per_group;
5589 * If we've gotten to this point, then the only
5590 * possibility is that the bad block inode meta data
5591 * is using a bad block.
5593 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
5594 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
5595 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
5597 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
5599 return BLOCK_CHANGED;
5601 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5608 /* Warn user that the block wasn't claimed */
5609 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
5614 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
5615 const char *name, int num, blk_t *new_block)
5617 ext2_filsys fs = ctx->fs;
5618 blk_t old_block = *new_block;
5621 struct problem_context pctx;
5623 clear_problem_context(&pctx);
5626 pctx.blk = old_block;
5629 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
5630 first_block + fs->super->s_blocks_per_group,
5631 num, ctx->block_found_map, new_block);
5634 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
5635 ext2fs_unmark_valid(fs);
5638 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
5640 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
5641 ext2fs_unmark_valid(fs);
5644 ext2fs_mark_super_dirty(fs);
5645 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
5646 pctx.blk2 = *new_block;
5647 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
5648 PR_1_RELOC_TO), &pctx);
5650 for (i = 0; i < num; i++) {
5652 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
5654 pctx.errcode = io_channel_read_blk(fs->io,
5655 old_block + i, 1, buf);
5657 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
5659 memset(buf, 0, fs->blocksize);
5661 pctx.blk = (*new_block) + i;
5662 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
5665 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
5667 ext2fs_free_mem(&buf);
5671 * This routine gets called at the end of pass 1 if bad blocks are
5672 * detected in the superblock, group descriptors, inode_bitmaps, or
5673 * block bitmaps. At this point, all of the blocks have been mapped
5674 * out, so we can try to allocate new block(s) to replace the bad
5677 static void handle_fs_bad_blocks(e2fsck_t ctx)
5679 ext2_filsys fs = ctx->fs;
5681 int first_block = fs->super->s_first_data_block;
5683 for (i = 0; i < fs->group_desc_count; i++) {
5684 if (ctx->invalid_block_bitmap_flag[i]) {
5685 new_table_block(ctx, first_block, i, _("block bitmap"),
5686 1, &fs->group_desc[i].bg_block_bitmap);
5688 if (ctx->invalid_inode_bitmap_flag[i]) {
5689 new_table_block(ctx, first_block, i, _("inode bitmap"),
5690 1, &fs->group_desc[i].bg_inode_bitmap);
5692 if (ctx->invalid_inode_table_flag[i]) {
5693 new_table_block(ctx, first_block, i, _("inode table"),
5694 fs->inode_blocks_per_group,
5695 &fs->group_desc[i].bg_inode_table);
5696 ctx->flags |= E2F_FLAG_RESTART;
5698 first_block += fs->super->s_blocks_per_group;
5700 ctx->invalid_bitmaps = 0;
5704 * This routine marks all blocks which are used by the superblock,
5705 * group descriptors, inode bitmaps, and block bitmaps.
5707 static void mark_table_blocks(e2fsck_t ctx)
5709 ext2_filsys fs = ctx->fs;
5713 struct problem_context pctx;
5715 clear_problem_context(&pctx);
5717 block = fs->super->s_first_data_block;
5718 for (i = 0; i < fs->group_desc_count; i++) {
5721 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
5724 * Mark the blocks used for the inode table
5726 if (fs->group_desc[i].bg_inode_table) {
5727 for (j = 0, b = fs->group_desc[i].bg_inode_table;
5728 j < fs->inode_blocks_per_group;
5730 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5733 if (fix_problem(ctx,
5734 PR_1_ITABLE_CONFLICT, &pctx)) {
5735 ctx->invalid_inode_table_flag[i]++;
5736 ctx->invalid_bitmaps++;
5739 ext2fs_mark_block_bitmap(ctx->block_found_map,
5746 * Mark block used for the block bitmap
5748 if (fs->group_desc[i].bg_block_bitmap) {
5749 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5750 fs->group_desc[i].bg_block_bitmap)) {
5751 pctx.blk = fs->group_desc[i].bg_block_bitmap;
5752 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
5753 ctx->invalid_block_bitmap_flag[i]++;
5754 ctx->invalid_bitmaps++;
5757 ext2fs_mark_block_bitmap(ctx->block_found_map,
5758 fs->group_desc[i].bg_block_bitmap);
5763 * Mark block used for the inode bitmap
5765 if (fs->group_desc[i].bg_inode_bitmap) {
5766 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5767 fs->group_desc[i].bg_inode_bitmap)) {
5768 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
5769 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
5770 ctx->invalid_inode_bitmap_flag[i]++;
5771 ctx->invalid_bitmaps++;
5774 ext2fs_mark_block_bitmap(ctx->block_found_map,
5775 fs->group_desc[i].bg_inode_bitmap);
5778 block += fs->super->s_blocks_per_group;
5783 * Thes subroutines short circuits ext2fs_get_blocks and
5784 * ext2fs_check_directory; we use them since we already have the inode
5785 * structure, so there's no point in letting the ext2fs library read
5788 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
5791 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5794 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5795 return EXT2_ET_CALLBACK_NOTHANDLED;
5797 for (i=0; i < EXT2_N_BLOCKS; i++)
5798 blocks[i] = ctx->stashed_inode->i_block[i];
5802 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
5803 struct ext2_inode *inode)
5805 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5807 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5808 return EXT2_ET_CALLBACK_NOTHANDLED;
5809 *inode = *ctx->stashed_inode;
5813 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
5814 struct ext2_inode *inode)
5816 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5818 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
5819 *ctx->stashed_inode = *inode;
5820 return EXT2_ET_CALLBACK_NOTHANDLED;
5823 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
5825 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5827 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5828 return EXT2_ET_CALLBACK_NOTHANDLED;
5830 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
5831 return EXT2_ET_NO_DIRECTORY;
5835 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
5837 ext2_filsys fs = ctx->fs;
5840 fs->get_blocks = pass1_get_blocks;
5841 fs->check_directory = pass1_check_directory;
5842 fs->read_inode = pass1_read_inode;
5843 fs->write_inode = pass1_write_inode;
5844 ctx->stashed_ino = 0;
5847 fs->check_directory = 0;
5849 fs->write_inode = 0;
5854 * pass1b.c --- Pass #1b of e2fsck
5856 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
5857 * only invoked if pass 1 discovered blocks which are in use by more
5860 * Pass1B scans the data blocks of all the inodes again, generating a
5861 * complete list of duplicate blocks and which inodes have claimed
5864 * Pass1C does a tree-traversal of the filesystem, to determine the
5865 * parent directories of these inodes. This step is necessary so that
5866 * e2fsck can print out the pathnames of affected inodes.
5868 * Pass1D is a reconciliation pass. For each inode with duplicate
5869 * blocks, the user is prompted if s/he would like to clone the file
5870 * (so that the file gets a fresh copy of the duplicated blocks) or
5871 * simply to delete the file.
5876 /* Needed for architectures where sizeof(int) != sizeof(void *) */
5877 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
5878 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
5880 /* Define an extension to the ext2 library's block count information */
5881 #define BLOCK_COUNT_EXTATTR (-5)
5885 struct block_el *next;
5890 struct inode_el *next;
5895 struct inode_el *inode_list;
5899 * This structure stores information about a particular inode which
5900 * is sharing blocks with other inodes. This information is collected
5901 * to display to the user, so that the user knows what files he or she
5902 * is dealing with, when trying to decide how to resolve the conflict
5903 * of multiply-claimed blocks.
5908 struct ext2_inode inode;
5909 struct block_el *block_list;
5912 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
5913 e2_blkcnt_t blockcnt, blk_t ref_blk,
5914 int ref_offset, void *priv_data);
5915 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5916 struct dup_inode *dp, char *block_buf);
5917 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5918 struct dup_inode *dp, char* block_buf);
5919 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
5921 static void pass1b(e2fsck_t ctx, char *block_buf);
5922 static void pass1c(e2fsck_t ctx, char *block_buf);
5923 static void pass1d(e2fsck_t ctx, char *block_buf);
5925 static int dup_inode_count = 0;
5927 static dict_t blk_dict, ino_dict;
5929 static ext2fs_inode_bitmap inode_dup_map;
5931 static int dict_int_cmp(const void *a, const void *b)
5942 * Add a duplicate block record
5944 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
5945 struct ext2_inode *inode)
5948 struct dup_block *db;
5949 struct dup_inode *di;
5950 struct block_el *blk_el;
5951 struct inode_el *ino_el;
5953 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5955 db = (struct dup_block *) dnode_get(n);
5957 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
5958 sizeof(struct dup_block), "duplicate block header");
5961 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
5963 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
5964 sizeof(struct inode_el), "inode element");
5965 ino_el->inode = ino;
5966 ino_el->next = db->inode_list;
5967 db->inode_list = ino_el;
5970 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
5972 di = (struct dup_inode *) dnode_get(n);
5974 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
5975 sizeof(struct dup_inode), "duplicate inode header");
5976 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
5977 di->num_dupblocks = 0;
5980 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
5982 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
5983 sizeof(struct block_el), "block element");
5984 blk_el->block = blk;
5985 blk_el->next = di->block_list;
5986 di->block_list = blk_el;
5987 di->num_dupblocks++;
5991 * Free a duplicate inode record
5993 static void inode_dnode_free(dnode_t *node)
5995 struct dup_inode *di;
5996 struct block_el *p, *next;
5998 di = (struct dup_inode *) dnode_get(node);
5999 for (p = di->block_list; p; p = next) {
6007 * Free a duplicate block record
6009 static void block_dnode_free(dnode_t *node)
6011 struct dup_block *db;
6012 struct inode_el *p, *next;
6014 db = (struct dup_block *) dnode_get(node);
6015 for (p = db->inode_list; p; p = next) {
6024 * Main procedure for handling duplicate blocks
6026 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
6028 ext2_filsys fs = ctx->fs;
6029 struct problem_context pctx;
6031 clear_problem_context(&pctx);
6033 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
6034 _("multiply claimed inode map"), &inode_dup_map);
6036 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
6037 ctx->flags |= E2F_FLAG_ABORT;
6041 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6042 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6043 dict_set_allocator(&ino_dict, inode_dnode_free);
6044 dict_set_allocator(&blk_dict, block_dnode_free);
6046 pass1b(ctx, block_buf);
6047 pass1c(ctx, block_buf);
6048 pass1d(ctx, block_buf);
6051 * Time to free all of the accumulated data structures that we
6052 * don't need anymore.
6054 dict_free_nodes(&ino_dict);
6055 dict_free_nodes(&blk_dict);
6059 * Scan the inodes looking for inodes that contain duplicate blocks.
6061 struct process_block_struct_1b {
6065 struct ext2_inode *inode;
6066 struct problem_context *pctx;
6069 static void pass1b(e2fsck_t ctx, char *block_buf)
6071 ext2_filsys fs = ctx->fs;
6073 struct ext2_inode inode;
6074 ext2_inode_scan scan;
6075 struct process_block_struct_1b pb;
6076 struct problem_context pctx;
6078 clear_problem_context(&pctx);
6080 if (!(ctx->options & E2F_OPT_PREEN))
6081 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
6082 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
6085 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6086 ctx->flags |= E2F_FLAG_ABORT;
6089 ctx->stashed_inode = &inode;
6092 pctx.str = "pass1b";
6094 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
6095 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
6098 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6099 ctx->flags |= E2F_FLAG_ABORT;
6104 pctx.ino = ctx->stashed_ino = ino;
6105 if ((ino != EXT2_BAD_INO) &&
6106 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
6113 if (ext2fs_inode_has_valid_blocks(&inode) ||
6114 (ino == EXT2_BAD_INO))
6115 pctx.errcode = ext2fs_block_iterate2(fs, ino,
6116 0, block_buf, process_pass1b_block, &pb);
6117 if (inode.i_file_acl)
6118 process_pass1b_block(fs, &inode.i_file_acl,
6119 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6120 if (pb.dup_blocks) {
6121 end_problem_latch(ctx, PR_LATCH_DBLOCK);
6122 if (ino >= EXT2_FIRST_INODE(fs->super) ||
6123 ino == EXT2_ROOT_INO)
6127 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6129 ext2fs_close_inode_scan(scan);
6130 e2fsck_use_inode_shortcuts(ctx, 0);
6133 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
6135 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6136 blk_t ref_blk FSCK_ATTR((unused)),
6137 int ref_offset FSCK_ATTR((unused)),
6140 struct process_block_struct_1b *p;
6143 if (HOLE_BLKADDR(*block_nr))
6145 p = (struct process_block_struct_1b *) priv_data;
6148 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
6151 /* OK, this is a duplicate block */
6152 if (p->ino != EXT2_BAD_INO) {
6153 p->pctx->blk = *block_nr;
6154 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
6157 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
6159 add_dupe(ctx, p->ino, *block_nr, p->inode);
6165 * Pass 1c: Scan directories for inodes with duplicate blocks. This
6166 * is used so that we can print pathnames when prompting the user for
6169 struct search_dir_struct {
6171 ext2_ino_t first_inode;
6172 ext2_ino_t max_inode;
6175 static int search_dirent_proc(ext2_ino_t dir, int entry,
6176 struct ext2_dir_entry *dirent,
6177 int offset FSCK_ATTR((unused)),
6178 int blocksize FSCK_ATTR((unused)),
6179 char *buf FSCK_ATTR((unused)),
6182 struct search_dir_struct *sd;
6183 struct dup_inode *p;
6186 sd = (struct search_dir_struct *) priv_data;
6188 if (dirent->inode > sd->max_inode)
6189 /* Should abort this inode, but not everything */
6192 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
6193 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
6196 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
6199 p = (struct dup_inode *) dnode_get(n);
6203 return(sd->count ? 0 : DIRENT_ABORT);
6207 static void pass1c(e2fsck_t ctx, char *block_buf)
6209 ext2_filsys fs = ctx->fs;
6210 struct search_dir_struct sd;
6211 struct problem_context pctx;
6213 clear_problem_context(&pctx);
6215 if (!(ctx->options & E2F_OPT_PREEN))
6216 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
6219 * Search through all directories to translate inodes to names
6220 * (by searching for the containing directory for that inode.)
6222 sd.count = dup_inode_count;
6223 sd.first_inode = EXT2_FIRST_INODE(fs->super);
6224 sd.max_inode = fs->super->s_inodes_count;
6225 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
6226 search_dirent_proc, &sd);
6229 static void pass1d(e2fsck_t ctx, char *block_buf)
6231 ext2_filsys fs = ctx->fs;
6232 struct dup_inode *p, *t;
6233 struct dup_block *q;
6234 ext2_ino_t *shared, ino;
6239 struct problem_context pctx;
6244 clear_problem_context(&pctx);
6246 if (!(ctx->options & E2F_OPT_PREEN))
6247 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
6248 e2fsck_read_bitmaps(ctx);
6250 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
6251 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
6252 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
6253 sizeof(ext2_ino_t) * dict_count(&ino_dict),
6254 "Shared inode list");
6255 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
6256 p = (struct dup_inode *) dnode_get(n);
6259 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
6260 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
6264 * Find all of the inodes which share blocks with this
6265 * one. First we find all of the duplicate blocks
6266 * belonging to this inode, and then search each block
6267 * get the list of inodes, and merge them together.
6269 for (s = p->block_list; s; s = s->next) {
6270 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
6272 continue; /* Should never happen... */
6273 q = (struct dup_block *) dnode_get(m);
6276 if (check_if_fs_block(ctx, s->block)) {
6282 * Add all inodes used by this block to the
6283 * shared[] --- which is a unique list, so
6284 * if an inode is already in shared[], don't
6287 for (r = q->inode_list; r; r = r->next) {
6288 if (r->inode == ino)
6290 for (i = 0; i < shared_len; i++)
6291 if (shared[i] == r->inode)
6293 if (i == shared_len) {
6294 shared[shared_len++] = r->inode;
6300 * Report the inode that we are working on
6302 pctx.inode = &p->inode;
6305 pctx.blkcount = p->num_dupblocks;
6306 pctx.num = meta_data ? shared_len+1 : shared_len;
6307 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
6312 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
6314 for (i = 0; i < shared_len; i++) {
6315 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
6317 continue; /* should never happen */
6318 t = (struct dup_inode *) dnode_get(m);
6320 * Report the inode that we are sharing with
6322 pctx.inode = &t->inode;
6323 pctx.ino = shared[i];
6325 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
6328 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
6331 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
6332 pctx.errcode = clone_file(ctx, ino, p, block_buf);
6334 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
6338 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
6339 delete_file(ctx, ino, p, block_buf);
6341 ext2fs_unmark_valid(fs);
6343 ext2fs_free_mem(&shared);
6347 * Drop the refcount on the dup_block structure, and clear the entry
6348 * in the block_dup_map if appropriate.
6350 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
6353 if (p->num_bad <= 0 ||
6354 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
6355 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
6358 static int delete_file_block(ext2_filsys fs,
6360 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6361 blk_t ref_block FSCK_ATTR((unused)),
6362 int ref_offset FSCK_ATTR((unused)),
6365 struct process_block_struct_1b *pb;
6366 struct dup_block *p;
6370 pb = (struct process_block_struct_1b *) priv_data;
6373 if (HOLE_BLKADDR(*block_nr))
6376 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6377 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6379 p = (struct dup_block *) dnode_get(n);
6380 decrement_badcount(ctx, *block_nr, p);
6382 com_err("delete_file_block", 0,
6383 _("internal error; can't find dup_blk for %d\n"),
6386 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6387 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6393 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6394 struct dup_inode *dp, char* block_buf)
6396 ext2_filsys fs = ctx->fs;
6397 struct process_block_struct_1b pb;
6398 struct ext2_inode inode;
6399 struct problem_context pctx;
6402 clear_problem_context(&pctx);
6403 pctx.ino = pb.ino = ino;
6404 pb.dup_blocks = dp->num_dupblocks;
6406 pctx.str = "delete_file";
6408 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6409 if (ext2fs_inode_has_valid_blocks(&inode))
6410 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6411 delete_file_block, &pb);
6413 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6414 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6415 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6416 if (ctx->inode_bad_map)
6417 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6418 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6420 /* Inode may have changed by block_iterate, so reread it */
6421 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6422 inode.i_links_count = 0;
6423 inode.i_dtime = time(0);
6424 if (inode.i_file_acl &&
6425 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6427 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6428 block_buf, -1, &count);
6429 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6434 pctx.blk = inode.i_file_acl;
6435 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
6438 * If the count is zero, then arrange to have the
6439 * block deleted. If the block is in the block_dup_map,
6440 * also call delete_file_block since it will take care
6441 * of keeping the accounting straight.
6444 ext2fs_test_block_bitmap(ctx->block_dup_map,
6446 delete_file_block(fs, &inode.i_file_acl,
6447 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6449 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
6452 struct clone_struct {
6459 static int clone_file_block(ext2_filsys fs,
6461 e2_blkcnt_t blockcnt,
6462 blk_t ref_block FSCK_ATTR((unused)),
6463 int ref_offset FSCK_ATTR((unused)),
6466 struct dup_block *p;
6469 struct clone_struct *cs = (struct clone_struct *) priv_data;
6475 if (HOLE_BLKADDR(*block_nr))
6478 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6479 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6481 p = (struct dup_block *) dnode_get(n);
6482 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
6485 cs->errcode = retval;
6488 if (cs->dir && (blockcnt >= 0)) {
6489 retval = ext2fs_set_dir_block(fs->dblist,
6490 cs->dir, new_block, blockcnt);
6492 cs->errcode = retval;
6497 retval = io_channel_read_blk(fs->io, *block_nr, 1,
6500 cs->errcode = retval;
6503 retval = io_channel_write_blk(fs->io, new_block, 1,
6506 cs->errcode = retval;
6509 decrement_badcount(ctx, *block_nr, p);
6510 *block_nr = new_block;
6511 ext2fs_mark_block_bitmap(ctx->block_found_map,
6513 ext2fs_mark_block_bitmap(fs->block_map, new_block);
6514 return BLOCK_CHANGED;
6516 com_err("clone_file_block", 0,
6517 _("internal error; can't find dup_blk for %d\n"),
6523 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6524 struct dup_inode *dp, char* block_buf)
6526 ext2_filsys fs = ctx->fs;
6528 struct clone_struct cs;
6529 struct problem_context pctx;
6532 struct inode_el *ino_el;
6533 struct dup_block *db;
6534 struct dup_inode *di;
6536 clear_problem_context(&pctx);
6540 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
6544 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
6548 pctx.str = "clone_file";
6549 if (ext2fs_inode_has_valid_blocks(&dp->inode))
6550 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6551 clone_file_block, &cs);
6552 ext2fs_mark_bb_dirty(fs);
6554 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6555 retval = pctx.errcode;
6559 com_err("clone_file", cs.errcode,
6560 _("returned from clone_file_block"));
6561 retval = cs.errcode;
6564 /* The inode may have changed on disk, so we have to re-read it */
6565 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
6566 blk = dp->inode.i_file_acl;
6567 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
6568 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
6570 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
6572 * If we cloned the EA block, find all other inodes
6573 * which refered to that EA block, and modify
6574 * them to point to the new EA block.
6576 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6577 db = (struct dup_block *) dnode_get(n);
6578 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
6579 if (ino_el->inode == ino)
6581 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
6582 di = (struct dup_inode *) dnode_get(n);
6583 if (di->inode.i_file_acl == blk) {
6584 di->inode.i_file_acl = dp->inode.i_file_acl;
6585 e2fsck_write_inode(ctx, ino_el->inode,
6586 &di->inode, "clone file EA");
6587 decrement_badcount(ctx, blk, db);
6593 ext2fs_free_mem(&cs.buf);
6598 * This routine returns 1 if a block overlaps with one of the superblocks,
6599 * group descriptors, inode bitmaps, or block bitmaps.
6601 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
6603 ext2_filsys fs = ctx->fs;
6607 block = fs->super->s_first_data_block;
6608 for (i = 0; i < fs->group_desc_count; i++) {
6610 /* Check superblocks/block group descriptros */
6611 if (ext2fs_bg_has_super(fs, i)) {
6612 if (test_block >= block &&
6613 (test_block <= block + fs->desc_blocks))
6617 /* Check the inode table */
6618 if ((fs->group_desc[i].bg_inode_table) &&
6619 (test_block >= fs->group_desc[i].bg_inode_table) &&
6620 (test_block < (fs->group_desc[i].bg_inode_table +
6621 fs->inode_blocks_per_group)))
6624 /* Check the bitmap blocks */
6625 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
6626 (test_block == fs->group_desc[i].bg_inode_bitmap))
6629 block += fs->super->s_blocks_per_group;
6634 * pass2.c --- check directory structure
6636 * Pass 2 of e2fsck iterates through all active directory inodes, and
6637 * applies to following tests to each directory entry in the directory
6638 * blocks in the inodes:
6640 * - The length of the directory entry (rec_len) should be at
6641 * least 8 bytes, and no more than the remaining space
6642 * left in the directory block.
6643 * - The length of the name in the directory entry (name_len)
6644 * should be less than (rec_len - 8).
6645 * - The inode number in the directory entry should be within
6647 * - The inode number should refer to a in-use inode.
6648 * - The first entry should be '.', and its inode should be
6649 * the inode of the directory.
6650 * - The second entry should be '..'.
6652 * To minimize disk seek time, the directory blocks are processed in
6653 * sorted order of block numbers.
6655 * Pass 2 also collects the following information:
6656 * - The inode numbers of the subdirectories for each directory.
6658 * Pass 2 relies on the following information from previous passes:
6659 * - The directory information collected in pass 1.
6660 * - The inode_used_map bitmap
6661 * - The inode_bad_map bitmap
6662 * - The inode_dir_map bitmap
6664 * Pass 2 frees the following data structures
6665 * - The inode_bad_map bitmap
6666 * - The inode_reg_map bitmap
6670 * Keeps track of how many times an inode is referenced.
6672 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
6673 static int check_dir_block(ext2_filsys fs,
6674 struct ext2_db_entry *dir_blocks_info,
6676 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
6677 struct problem_context *pctx);
6678 static int update_dir_block(ext2_filsys fs,
6680 e2_blkcnt_t blockcnt,
6684 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
6685 static int htree_depth(struct dx_dir_info *dx_dir,
6686 struct dx_dirblock_info *dx_db);
6687 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
6689 struct check_dir_struct {
6691 struct problem_context pctx;
6696 static void e2fsck_pass2(e2fsck_t ctx)
6698 struct ext2_super_block *sb = ctx->fs->super;
6699 struct problem_context pctx;
6700 ext2_filsys fs = ctx->fs;
6702 struct dir_info *dir;
6703 struct check_dir_struct cd;
6704 struct dx_dir_info *dx_dir;
6705 struct dx_dirblock_info *dx_db, *dx_parent;
6711 clear_problem_context(&cd.pctx);
6715 if (!(ctx->options & E2F_OPT_PREEN))
6716 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
6718 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
6719 0, ctx->inode_link_info,
6721 if (cd.pctx.errcode) {
6722 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
6723 ctx->flags |= E2F_FLAG_ABORT;
6726 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
6727 "directory scan buffer");
6730 * Set up the parent pointer for the root directory, if
6731 * present. (If the root directory is not present, we will
6732 * create it in pass 3.)
6734 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
6736 dir->parent = EXT2_ROOT_INO;
6741 cd.max = ext2fs_dblist_count(fs->dblist);
6744 (void) (ctx->progress)(ctx, 2, 0, cd.max);
6746 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
6747 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
6749 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
6751 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6753 if (cd.pctx.errcode) {
6754 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
6755 ctx->flags |= E2F_FLAG_ABORT;
6760 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
6761 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6763 if (dx_dir->numblocks == 0)
6765 clear_problem_context(&pctx);
6767 pctx.dir = dx_dir->ino;
6768 dx_db = dx_dir->dx_block;
6769 if (dx_db->flags & DX_FLAG_REFERENCED)
6770 dx_db->flags |= DX_FLAG_DUP_REF;
6772 dx_db->flags |= DX_FLAG_REFERENCED;
6774 * Find all of the first and last leaf blocks, and
6775 * update their parent's min and max hash values
6777 for (b=0, dx_db = dx_dir->dx_block;
6778 b < dx_dir->numblocks;
6780 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
6781 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
6783 dx_parent = &dx_dir->dx_block[dx_db->parent];
6785 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
6787 if (dx_db->flags & DX_FLAG_FIRST)
6788 dx_parent->min_hash = dx_db->min_hash;
6790 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
6792 if (dx_db->flags & DX_FLAG_LAST)
6793 dx_parent->max_hash = dx_db->max_hash;
6796 for (b=0, dx_db = dx_dir->dx_block;
6797 b < dx_dir->numblocks;
6800 pctx.group = dx_db->parent;
6802 if (!(dx_db->flags & DX_FLAG_FIRST) &&
6803 (dx_db->min_hash < dx_db->node_min_hash)) {
6804 pctx.blk = dx_db->min_hash;
6805 pctx.blk2 = dx_db->node_min_hash;
6806 code = PR_2_HTREE_MIN_HASH;
6807 fix_problem(ctx, code, &pctx);
6810 if (dx_db->type == DX_DIRBLOCK_LEAF) {
6811 depth = htree_depth(dx_dir, dx_db);
6812 if (depth != dx_dir->depth) {
6813 code = PR_2_HTREE_BAD_DEPTH;
6814 fix_problem(ctx, code, &pctx);
6819 * This test doesn't apply for the root block
6823 (dx_db->max_hash > dx_db->node_max_hash)) {
6824 pctx.blk = dx_db->max_hash;
6825 pctx.blk2 = dx_db->node_max_hash;
6826 code = PR_2_HTREE_MAX_HASH;
6827 fix_problem(ctx, code, &pctx);
6830 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
6831 code = PR_2_HTREE_NOTREF;
6832 fix_problem(ctx, code, &pctx);
6834 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
6835 code = PR_2_HTREE_DUPREF;
6836 fix_problem(ctx, code, &pctx);
6842 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
6843 clear_htree(ctx, dx_dir->ino);
6844 dx_dir->numblocks = 0;
6848 ext2fs_free_mem(&buf);
6849 ext2fs_free_dblist(fs->dblist);
6851 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
6852 ctx->inode_bad_map = 0;
6853 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
6854 ctx->inode_reg_map = 0;
6856 clear_problem_context(&pctx);
6857 if (ctx->large_files) {
6858 if (!(sb->s_feature_ro_compat &
6859 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
6860 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
6861 sb->s_feature_ro_compat |=
6862 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6863 ext2fs_mark_super_dirty(fs);
6865 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
6866 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
6867 ext2fs_update_dynamic_rev(fs);
6868 ext2fs_mark_super_dirty(fs);
6870 } else if (!ctx->large_files &&
6871 (sb->s_feature_ro_compat &
6872 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
6873 if (fs->flags & EXT2_FLAG_RW) {
6874 sb->s_feature_ro_compat &=
6875 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6876 ext2fs_mark_super_dirty(fs);
6882 #define MAX_DEPTH 32000
6883 static int htree_depth(struct dx_dir_info *dx_dir,
6884 struct dx_dirblock_info *dx_db)
6888 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
6889 dx_db = &dx_dir->dx_block[dx_db->parent];
6895 static int dict_de_cmp(const void *a, const void *b)
6897 const struct ext2_dir_entry *de_a, *de_b;
6900 de_a = (const struct ext2_dir_entry *) a;
6901 a_len = de_a->name_len & 0xFF;
6902 de_b = (const struct ext2_dir_entry *) b;
6903 b_len = de_b->name_len & 0xFF;
6906 return (a_len - b_len);
6908 return strncmp(de_a->name, de_b->name, a_len);
6912 * This is special sort function that makes sure that directory blocks
6913 * with a dirblock of zero are sorted to the beginning of the list.
6914 * This guarantees that the root node of the htree directories are
6915 * processed first, so we know what hash version to use.
6917 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
6919 const struct ext2_db_entry *db_a =
6920 (const struct ext2_db_entry *) a;
6921 const struct ext2_db_entry *db_b =
6922 (const struct ext2_db_entry *) b;
6924 if (db_a->blockcnt && !db_b->blockcnt)
6927 if (!db_a->blockcnt && db_b->blockcnt)
6930 if (db_a->blk != db_b->blk)
6931 return (int) (db_a->blk - db_b->blk);
6933 if (db_a->ino != db_b->ino)
6934 return (int) (db_a->ino - db_b->ino);
6936 return (int) (db_a->blockcnt - db_b->blockcnt);
6941 * Make sure the first entry in the directory is '.', and that the
6942 * directory entry is sane.
6944 static int check_dot(e2fsck_t ctx,
6945 struct ext2_dir_entry *dirent,
6946 ext2_ino_t ino, struct problem_context *pctx)
6948 struct ext2_dir_entry *nextdir;
6955 problem = PR_2_MISSING_DOT;
6956 else if (((dirent->name_len & 0xFF) != 1) ||
6957 (dirent->name[0] != '.'))
6958 problem = PR_2_1ST_NOT_DOT;
6959 else if (dirent->name[1] != '\0')
6960 problem = PR_2_DOT_NULL_TERM;
6963 if (fix_problem(ctx, problem, pctx)) {
6964 if (dirent->rec_len < 12)
6965 dirent->rec_len = 12;
6966 dirent->inode = ino;
6967 dirent->name_len = 1;
6968 dirent->name[0] = '.';
6969 dirent->name[1] = '\0';
6974 if (dirent->inode != ino) {
6975 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
6976 dirent->inode = ino;
6980 if (dirent->rec_len > 12) {
6981 new_len = dirent->rec_len - 12;
6984 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
6985 nextdir = (struct ext2_dir_entry *)
6986 ((char *) dirent + 12);
6987 dirent->rec_len = 12;
6988 nextdir->rec_len = new_len;
6990 nextdir->name_len = 0;
6999 * Make sure the second entry in the directory is '..', and that the
7000 * directory entry is sane. We do not check the inode number of '..'
7001 * here; this gets done in pass 3.
7003 static int check_dotdot(e2fsck_t ctx,
7004 struct ext2_dir_entry *dirent,
7005 struct dir_info *dir, struct problem_context *pctx)
7010 problem = PR_2_MISSING_DOT_DOT;
7011 else if (((dirent->name_len & 0xFF) != 2) ||
7012 (dirent->name[0] != '.') ||
7013 (dirent->name[1] != '.'))
7014 problem = PR_2_2ND_NOT_DOT_DOT;
7015 else if (dirent->name[2] != '\0')
7016 problem = PR_2_DOT_DOT_NULL_TERM;
7019 if (fix_problem(ctx, problem, pctx)) {
7020 if (dirent->rec_len < 12)
7021 dirent->rec_len = 12;
7023 * Note: we don't have the parent inode just
7024 * yet, so we will fill it in with the root
7025 * inode. This will get fixed in pass 3.
7027 dirent->inode = EXT2_ROOT_INO;
7028 dirent->name_len = 2;
7029 dirent->name[0] = '.';
7030 dirent->name[1] = '.';
7031 dirent->name[2] = '\0';
7036 dir->dotdot = dirent->inode;
7041 * Check to make sure a directory entry doesn't contain any illegal
7044 static int check_name(e2fsck_t ctx,
7045 struct ext2_dir_entry *dirent,
7046 struct problem_context *pctx)
7052 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
7053 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
7055 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
7058 dirent->name[i] = '.';
7067 * Check the directory filetype (if present)
7071 * Given a mode, return the ext2 file type
7073 static int ext2_file_type(unsigned int mode)
7075 if (LINUX_S_ISREG(mode))
7076 return EXT2_FT_REG_FILE;
7078 if (LINUX_S_ISDIR(mode))
7081 if (LINUX_S_ISCHR(mode))
7082 return EXT2_FT_CHRDEV;
7084 if (LINUX_S_ISBLK(mode))
7085 return EXT2_FT_BLKDEV;
7087 if (LINUX_S_ISLNK(mode))
7088 return EXT2_FT_SYMLINK;
7090 if (LINUX_S_ISFIFO(mode))
7091 return EXT2_FT_FIFO;
7093 if (LINUX_S_ISSOCK(mode))
7094 return EXT2_FT_SOCK;
7099 static _INLINE_ int check_filetype(e2fsck_t ctx,
7100 struct ext2_dir_entry *dirent,
7101 struct problem_context *pctx)
7103 int filetype = dirent->name_len >> 8;
7104 int should_be = EXT2_FT_UNKNOWN;
7105 struct ext2_inode inode;
7107 if (!(ctx->fs->super->s_feature_incompat &
7108 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
7109 if (filetype == 0 ||
7110 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
7112 dirent->name_len = dirent->name_len & 0xFF;
7116 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
7117 should_be = EXT2_FT_DIR;
7118 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
7120 should_be = EXT2_FT_REG_FILE;
7121 } else if (ctx->inode_bad_map &&
7122 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7126 e2fsck_read_inode(ctx, dirent->inode, &inode,
7128 should_be = ext2_file_type(inode.i_mode);
7130 if (filetype == should_be)
7132 pctx->num = should_be;
7134 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
7138 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
7143 static void parse_int_node(ext2_filsys fs,
7144 struct ext2_db_entry *db,
7145 struct check_dir_struct *cd,
7146 struct dx_dir_info *dx_dir,
7149 struct ext2_dx_root_info *root;
7150 struct ext2_dx_entry *ent;
7151 struct ext2_dx_countlimit *limit;
7152 struct dx_dirblock_info *dx_db;
7153 int i, expect_limit, count;
7155 ext2_dirhash_t min_hash = 0xffffffff;
7156 ext2_dirhash_t max_hash = 0;
7157 ext2_dirhash_t hash = 0, prev_hash;
7159 if (db->blockcnt == 0) {
7160 root = (struct ext2_dx_root_info *) (block_buf + 24);
7161 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
7163 ent = (struct ext2_dx_entry *) (block_buf+8);
7165 limit = (struct ext2_dx_countlimit *) ent;
7167 count = ext2fs_le16_to_cpu(limit->count);
7168 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
7169 sizeof(struct ext2_dx_entry);
7170 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
7171 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
7172 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
7173 goto clear_and_exit;
7175 if (count > expect_limit) {
7176 cd->pctx.num = count;
7177 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
7178 goto clear_and_exit;
7179 count = expect_limit;
7182 for (i=0; i < count; i++) {
7184 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
7185 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
7186 /* Check to make sure the block is valid */
7187 if (blk > (blk_t) dx_dir->numblocks) {
7189 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
7191 goto clear_and_exit;
7193 if (hash < prev_hash &&
7194 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
7195 goto clear_and_exit;
7196 dx_db = &dx_dir->dx_block[blk];
7197 if (dx_db->flags & DX_FLAG_REFERENCED) {
7198 dx_db->flags |= DX_FLAG_DUP_REF;
7200 dx_db->flags |= DX_FLAG_REFERENCED;
7201 dx_db->parent = db->blockcnt;
7203 if (hash < min_hash)
7205 if (hash > max_hash)
7207 dx_db->node_min_hash = hash;
7209 dx_db->node_max_hash =
7210 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
7212 dx_db->node_max_hash = 0xfffffffe;
7213 dx_db->flags |= DX_FLAG_LAST;
7216 dx_db->flags |= DX_FLAG_FIRST;
7218 dx_db = &dx_dir->dx_block[db->blockcnt];
7219 dx_db->min_hash = min_hash;
7220 dx_db->max_hash = max_hash;
7224 clear_htree(cd->ctx, cd->pctx.ino);
7225 dx_dir->numblocks = 0;
7227 #endif /* ENABLE_HTREE */
7230 * Given a busted directory, try to salvage it somehow.
7233 static void salvage_directory(ext2_filsys fs,
7234 struct ext2_dir_entry *dirent,
7235 struct ext2_dir_entry *prev,
7236 unsigned int *offset)
7238 char *cp = (char *) dirent;
7239 int left = fs->blocksize - *offset - dirent->rec_len;
7240 int name_len = dirent->name_len & 0xFF;
7243 * Special case of directory entry of size 8: copy what's left
7244 * of the directory block up to cover up the invalid hole.
7246 if ((left >= 12) && (dirent->rec_len == 8)) {
7247 memmove(cp, cp+8, left);
7248 memset(cp + left, 0, 8);
7252 * If the directory entry overruns the end of the directory
7253 * block, and the name is small enough to fit, then adjust the
7257 (name_len + 8 <= dirent->rec_len + left) &&
7258 dirent->inode <= fs->super->s_inodes_count &&
7259 strnlen(dirent->name, name_len) == name_len) {
7260 dirent->rec_len += left;
7264 * If the directory entry is a multiple of four, so it is
7265 * valid, let the previous directory entry absorb the invalid
7268 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
7269 prev->rec_len += dirent->rec_len;
7270 *offset += dirent->rec_len;
7274 * Default salvage method --- kill all of the directory
7275 * entries for the rest of the block. We will either try to
7276 * absorb it into the previous directory entry, or create a
7277 * new empty directory entry the rest of the directory block.
7280 prev->rec_len += fs->blocksize - *offset;
7281 *offset = fs->blocksize;
7283 dirent->rec_len = fs->blocksize - *offset;
7284 dirent->name_len = 0;
7289 static int check_dir_block(ext2_filsys fs,
7290 struct ext2_db_entry *db,
7293 struct dir_info *subdir, *dir;
7294 struct dx_dir_info *dx_dir;
7296 struct dx_dirblock_info *dx_db = 0;
7297 #endif /* ENABLE_HTREE */
7298 struct ext2_dir_entry *dirent, *prev;
7299 ext2_dirhash_t hash;
7300 unsigned int offset = 0;
7301 int dir_modified = 0;
7303 blk_t block_nr = db->blk;
7304 ext2_ino_t ino = db->ino;
7306 struct check_dir_struct *cd;
7310 struct ext2_dx_root_info *root;
7311 struct ext2_dx_countlimit *limit;
7312 static dict_t de_dict;
7313 struct problem_context pctx;
7316 cd = (struct check_dir_struct *) priv_data;
7320 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7321 return DIRENT_ABORT;
7323 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
7324 return DIRENT_ABORT;
7327 * Make sure the inode is still in use (could have been
7328 * deleted in the duplicate/bad blocks pass.
7330 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
7334 cd->pctx.blk = block_nr;
7335 cd->pctx.blkcount = db->blockcnt;
7337 cd->pctx.dirent = 0;
7341 if (allocate_dir_block(ctx, db, &cd->pctx))
7351 if (ctx->dirs_to_hash &&
7352 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
7355 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
7356 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
7357 cd->pctx.errcode = 0; /* We'll handle this ourselves */
7358 if (cd->pctx.errcode) {
7359 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
7360 ctx->flags |= E2F_FLAG_ABORT;
7361 return DIRENT_ABORT;
7363 memset(buf, 0, fs->blocksize);
7366 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
7367 if (dx_dir && dx_dir->numblocks) {
7368 if (db->blockcnt >= dx_dir->numblocks) {
7369 printf("XXX should never happen!!!\n");
7372 dx_db = &dx_dir->dx_block[db->blockcnt];
7373 dx_db->type = DX_DIRBLOCK_LEAF;
7374 dx_db->phys = block_nr;
7375 dx_db->min_hash = ~0;
7376 dx_db->max_hash = 0;
7378 dirent = (struct ext2_dir_entry *) buf;
7379 limit = (struct ext2_dx_countlimit *) (buf+8);
7380 if (db->blockcnt == 0) {
7381 root = (struct ext2_dx_root_info *) (buf + 24);
7382 dx_db->type = DX_DIRBLOCK_ROOT;
7383 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
7384 if ((root->reserved_zero ||
7385 root->info_length < 8 ||
7386 root->indirect_levels > 1) &&
7387 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
7388 clear_htree(ctx, ino);
7389 dx_dir->numblocks = 0;
7392 dx_dir->hashversion = root->hash_version;
7393 dx_dir->depth = root->indirect_levels + 1;
7394 } else if ((dirent->inode == 0) &&
7395 (dirent->rec_len == fs->blocksize) &&
7396 (dirent->name_len == 0) &&
7397 (ext2fs_le16_to_cpu(limit->limit) ==
7398 ((fs->blocksize-8) /
7399 sizeof(struct ext2_dx_entry))))
7400 dx_db->type = DX_DIRBLOCK_NODE;
7402 #endif /* ENABLE_HTREE */
7404 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
7408 dirent = (struct ext2_dir_entry *) (buf + offset);
7409 cd->pctx.dirent = dirent;
7410 cd->pctx.num = offset;
7411 if (((offset + dirent->rec_len) > fs->blocksize) ||
7412 (dirent->rec_len < 12) ||
7413 ((dirent->rec_len % 4) != 0) ||
7414 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
7415 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
7416 salvage_directory(fs, dirent, prev, &offset);
7420 goto abort_free_dict;
7422 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
7423 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
7424 dirent->name_len = EXT2_NAME_LEN;
7429 if (dot_state == 0) {
7430 if (check_dot(ctx, dirent, ino, &cd->pctx))
7432 } else if (dot_state == 1) {
7433 dir = e2fsck_get_dir_info(ctx, ino);
7435 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
7436 goto abort_free_dict;
7438 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
7440 } else if (dirent->inode == ino) {
7441 problem = PR_2_LINK_DOT;
7442 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
7452 * Make sure the inode listed is a legal one.
7454 if (((dirent->inode != EXT2_ROOT_INO) &&
7455 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
7456 (dirent->inode > fs->super->s_inodes_count)) {
7457 problem = PR_2_BAD_INO;
7458 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
7461 * If the inode is unused, offer to clear it.
7463 problem = PR_2_UNUSED_INODE;
7464 } else if (ctx->inode_bb_map &&
7465 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
7468 * If the inode is in a bad block, offer to
7471 problem = PR_2_BB_INODE;
7472 } else if ((dot_state > 1) &&
7473 ((dirent->name_len & 0xFF) == 1) &&
7474 (dirent->name[0] == '.')) {
7476 * If there's a '.' entry in anything other
7477 * than the first directory entry, it's a
7478 * duplicate entry that should be removed.
7480 problem = PR_2_DUP_DOT;
7481 } else if ((dot_state > 1) &&
7482 ((dirent->name_len & 0xFF) == 2) &&
7483 (dirent->name[0] == '.') &&
7484 (dirent->name[1] == '.')) {
7486 * If there's a '..' entry in anything other
7487 * than the second directory entry, it's a
7488 * duplicate entry that should be removed.
7490 problem = PR_2_DUP_DOT_DOT;
7491 } else if ((dot_state > 1) &&
7492 (dirent->inode == EXT2_ROOT_INO)) {
7494 * Don't allow links to the root directory.
7495 * We check this specially to make sure we
7496 * catch this error case even if the root
7497 * directory hasn't been created yet.
7499 problem = PR_2_LINK_ROOT;
7500 } else if ((dot_state > 1) &&
7501 (dirent->name_len & 0xFF) == 0) {
7503 * Don't allow zero-length directory names.
7505 problem = PR_2_NULL_NAME;
7509 if (fix_problem(ctx, problem, &cd->pctx)) {
7514 ext2fs_unmark_valid(fs);
7515 if (problem == PR_2_BAD_INO)
7521 * If the inode was marked as having bad fields in
7522 * pass1, process it and offer to fix/clear it.
7523 * (We wait until now so that we can display the
7524 * pathname to the user.)
7526 if (ctx->inode_bad_map &&
7527 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7529 if (e2fsck_process_bad_inode(ctx, ino,
7531 buf + fs->blocksize)) {
7536 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7537 return DIRENT_ABORT;
7540 if (check_name(ctx, dirent, &cd->pctx))
7543 if (check_filetype(ctx, dirent, &cd->pctx))
7548 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
7549 (dirent->name_len & 0xFF),
7550 fs->super->s_hash_seed, &hash, 0);
7551 if (hash < dx_db->min_hash)
7552 dx_db->min_hash = hash;
7553 if (hash > dx_db->max_hash)
7554 dx_db->max_hash = hash;
7559 * If this is a directory, then mark its parent in its
7560 * dir_info structure. If the parent field is already
7561 * filled in, then this directory has more than one
7562 * hard link. We assume the first link is correct,
7563 * and ask the user if he/she wants to clear this one.
7565 if ((dot_state > 1) &&
7566 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7568 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
7570 cd->pctx.ino = dirent->inode;
7571 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
7572 goto abort_free_dict;
7574 if (subdir->parent) {
7575 cd->pctx.ino2 = subdir->parent;
7576 if (fix_problem(ctx, PR_2_LINK_DIR,
7584 subdir->parent = ino;
7589 } else if (dict_lookup(&de_dict, dirent)) {
7590 clear_problem_context(&pctx);
7592 pctx.dirent = dirent;
7593 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
7594 if (!ctx->dirs_to_hash)
7595 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
7596 if (ctx->dirs_to_hash)
7597 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
7600 dict_alloc_insert(&de_dict, dirent, dirent);
7602 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
7605 ctx->fs_links_count++;
7606 ctx->fs_total_count++;
7609 offset += dirent->rec_len;
7611 } while (offset < fs->blocksize);
7614 cd->pctx.dir = cd->pctx.ino;
7615 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
7616 (dx_db->type == DX_DIRBLOCK_NODE))
7617 parse_int_node(fs, db, cd, dx_dir, buf);
7619 #endif /* ENABLE_HTREE */
7620 if (offset != fs->blocksize) {
7621 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
7622 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
7623 dirent->rec_len = cd->pctx.num;
7628 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
7629 if (cd->pctx.errcode) {
7630 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
7632 goto abort_free_dict;
7634 ext2fs_mark_changed(fs);
7636 dict_free_nodes(&de_dict);
7639 dict_free_nodes(&de_dict);
7640 ctx->flags |= E2F_FLAG_ABORT;
7641 return DIRENT_ABORT;
7645 * This function is called to deallocate a block, and is an interator
7646 * functioned called by deallocate inode via ext2fs_iterate_block().
7648 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
7649 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
7650 blk_t ref_block FSCK_ATTR((unused)),
7651 int ref_offset FSCK_ATTR((unused)),
7654 e2fsck_t ctx = (e2fsck_t) priv_data;
7656 if (HOLE_BLKADDR(*block_nr))
7658 if ((*block_nr < fs->super->s_first_data_block) ||
7659 (*block_nr >= fs->super->s_blocks_count))
7661 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
7662 ext2fs_block_alloc_stats(fs, *block_nr, -1);
7667 * This fuction deallocates an inode
7669 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
7671 ext2_filsys fs = ctx->fs;
7672 struct ext2_inode inode;
7673 struct problem_context pctx;
7676 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
7677 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
7678 inode.i_links_count = 0;
7679 inode.i_dtime = time(0);
7680 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
7681 clear_problem_context(&pctx);
7685 * Fix up the bitmaps...
7687 e2fsck_read_bitmaps(ctx);
7688 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
7689 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
7690 if (ctx->inode_bad_map)
7691 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7692 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
7694 if (inode.i_file_acl &&
7695 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
7696 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
7697 block_buf, -1, &count);
7698 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
7703 pctx.blk = inode.i_file_acl;
7704 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
7705 ctx->flags |= E2F_FLAG_ABORT;
7709 ext2fs_unmark_block_bitmap(ctx->block_found_map,
7711 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
7713 inode.i_file_acl = 0;
7716 if (!ext2fs_inode_has_valid_blocks(&inode))
7719 if (LINUX_S_ISREG(inode.i_mode) &&
7720 (inode.i_size_high || inode.i_size & 0x80000000UL))
7723 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7724 deallocate_inode_block, ctx);
7726 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
7727 ctx->flags |= E2F_FLAG_ABORT;
7733 * This fuction clears the htree flag on an inode
7735 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
7737 struct ext2_inode inode;
7739 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
7740 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
7741 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
7742 if (ctx->dirs_to_hash)
7743 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
7747 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
7748 ext2_ino_t ino, char *buf)
7750 ext2_filsys fs = ctx->fs;
7751 struct ext2_inode inode;
7752 int inode_modified = 0;
7754 unsigned char *frag, *fsize;
7755 struct problem_context pctx;
7758 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
7760 clear_problem_context(&pctx);
7763 pctx.inode = &inode;
7765 if (inode.i_file_acl &&
7766 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
7767 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
7768 inode.i_file_acl = 0;
7769 #ifdef EXT2FS_ENABLE_SWAPFS
7771 * This is a special kludge to deal with long symlinks
7772 * on big endian systems. i_blocks had already been
7773 * decremented earlier in pass 1, but since i_file_acl
7774 * hadn't yet been cleared, ext2fs_read_inode()
7775 * assumed that the file was short symlink and would
7776 * not have byte swapped i_block[0]. Hence, we have
7777 * to byte-swap it here.
7779 if (LINUX_S_ISLNK(inode.i_mode) &&
7780 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
7781 (inode.i_blocks == fs->blocksize >> 9))
7782 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
7788 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
7789 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
7790 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
7791 !(LINUX_S_ISSOCK(inode.i_mode)))
7792 problem = PR_2_BAD_MODE;
7793 else if (LINUX_S_ISCHR(inode.i_mode)
7794 && !e2fsck_pass1_check_device_inode(fs, &inode))
7795 problem = PR_2_BAD_CHAR_DEV;
7796 else if (LINUX_S_ISBLK(inode.i_mode)
7797 && !e2fsck_pass1_check_device_inode(fs, &inode))
7798 problem = PR_2_BAD_BLOCK_DEV;
7799 else if (LINUX_S_ISFIFO(inode.i_mode)
7800 && !e2fsck_pass1_check_device_inode(fs, &inode))
7801 problem = PR_2_BAD_FIFO;
7802 else if (LINUX_S_ISSOCK(inode.i_mode)
7803 && !e2fsck_pass1_check_device_inode(fs, &inode))
7804 problem = PR_2_BAD_SOCKET;
7805 else if (LINUX_S_ISLNK(inode.i_mode)
7806 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
7807 problem = PR_2_INVALID_SYMLINK;
7811 if (fix_problem(ctx, problem, &pctx)) {
7812 deallocate_inode(ctx, ino, 0);
7813 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7821 if (inode.i_faddr) {
7822 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
7829 switch (fs->super->s_creator_os) {
7831 frag = &inode.osd2.linux2.l_i_frag;
7832 fsize = &inode.osd2.linux2.l_i_fsize;
7835 frag = &inode.osd2.hurd2.h_i_frag;
7836 fsize = &inode.osd2.hurd2.h_i_fsize;
7839 frag = &inode.osd2.masix2.m_i_frag;
7840 fsize = &inode.osd2.masix2.m_i_fsize;
7845 if (frag && *frag) {
7847 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
7854 if (fsize && *fsize) {
7856 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
7864 if (inode.i_file_acl &&
7865 ((inode.i_file_acl < fs->super->s_first_data_block) ||
7866 (inode.i_file_acl >= fs->super->s_blocks_count))) {
7867 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
7868 inode.i_file_acl = 0;
7873 if (inode.i_dir_acl &&
7874 LINUX_S_ISDIR(inode.i_mode)) {
7875 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
7876 inode.i_dir_acl = 0;
7883 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
7885 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7891 * allocate_dir_block --- this function allocates a new directory
7892 * block for a particular inode; this is done if a directory has
7893 * a "hole" in it, or if a directory has a illegal block number
7894 * that was zeroed out and now needs to be replaced.
7896 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
7897 struct problem_context *pctx)
7899 ext2_filsys fs = ctx->fs;
7902 struct ext2_inode inode;
7904 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
7908 * Read the inode and block bitmaps in; we'll be messing with
7911 e2fsck_read_bitmaps(ctx);
7914 * First, find a free block
7916 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7917 if (pctx->errcode) {
7918 pctx->str = "ext2fs_new_block";
7919 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7922 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7923 ext2fs_mark_block_bitmap(fs->block_map, blk);
7924 ext2fs_mark_bb_dirty(fs);
7927 * Now let's create the actual data block for the inode
7930 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
7932 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
7933 EXT2_ROOT_INO, &block);
7935 if (pctx->errcode) {
7936 pctx->str = "ext2fs_new_dir_block";
7937 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7941 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
7942 ext2fs_free_mem(&block);
7943 if (pctx->errcode) {
7944 pctx->str = "ext2fs_write_dir_block";
7945 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7950 * Update the inode block count
7952 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
7953 inode.i_blocks += fs->blocksize / 512;
7954 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
7955 inode.i_size = (db->blockcnt+1) * fs->blocksize;
7956 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
7959 * Finally, update the block pointers for the inode
7962 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
7963 0, update_dir_block, db);
7964 if (pctx->errcode) {
7965 pctx->str = "ext2fs_block_iterate";
7966 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7974 * This is a helper function for allocate_dir_block().
7976 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
7978 e2_blkcnt_t blockcnt,
7979 blk_t ref_block FSCK_ATTR((unused)),
7980 int ref_offset FSCK_ATTR((unused)),
7983 struct ext2_db_entry *db;
7985 db = (struct ext2_db_entry *) priv_data;
7986 if (db->blockcnt == (int) blockcnt) {
7987 *block_nr = db->blk;
7988 return BLOCK_CHANGED;
7994 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
7996 * Pass #3 assures that all directories are connected to the
7997 * filesystem tree, using the following algorithm:
7999 * First, the root directory is checked to make sure it exists; if
8000 * not, e2fsck will offer to create a new one. It is then marked as
8003 * Then, pass3 interates over all directory inodes; for each directory
8004 * it attempts to trace up the filesystem tree, using dirinfo.parent
8005 * until it reaches a directory which has been marked "done". If it
8006 * can not do so, then the directory must be disconnected, and e2fsck
8007 * will offer to reconnect it to /lost+found. While it is chasing
8008 * parent pointers up the filesystem tree, if pass3 sees a directory
8009 * twice, then it has detected a filesystem loop, and it will again
8010 * offer to reconnect the directory to /lost+found in to break the
8013 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
8014 * reconnect inodes to /lost+found; this subroutine is also used by
8015 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
8016 * is responsible for creating /lost+found if it does not exist.
8018 * Pass 3 frees the following data structures:
8019 * - The dirinfo directory information cache.
8022 static void check_root(e2fsck_t ctx);
8023 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8024 struct problem_context *pctx);
8025 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
8027 static ext2fs_inode_bitmap inode_loop_detect;
8028 static ext2fs_inode_bitmap inode_done_map;
8030 static void e2fsck_pass3(e2fsck_t ctx)
8032 ext2_filsys fs = ctx->fs;
8034 struct problem_context pctx;
8035 struct dir_info *dir;
8036 unsigned long maxdirs, count;
8038 clear_problem_context(&pctx);
8042 if (!(ctx->options & E2F_OPT_PREEN))
8043 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
8046 * Allocate some bitmaps to do loop detection.
8048 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
8052 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
8053 ctx->flags |= E2F_FLAG_ABORT;
8057 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8060 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
8062 maxdirs = e2fsck_get_num_dirinfo(ctx);
8066 if ((ctx->progress)(ctx, 3, 0, maxdirs))
8069 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
8070 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8072 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
8074 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
8075 if (check_directory(ctx, dir, &pctx))
8080 * Force the creation of /lost+found if not present
8082 if ((ctx->flags & E2F_OPT_READONLY) == 0)
8083 e2fsck_get_lost_and_found(ctx, 1);
8086 * If there are any directories that need to be indexed or
8087 * optimized, do it here.
8089 e2fsck_rehash_directories(ctx);
8092 e2fsck_free_dir_info(ctx);
8093 ext2fs_free_inode_bitmap(inode_loop_detect);
8094 inode_loop_detect = 0;
8095 ext2fs_free_inode_bitmap(inode_done_map);
8100 * This makes sure the root inode is present; if not, we ask if the
8101 * user wants us to create it. Not creating it is a fatal error.
8103 static void check_root(e2fsck_t ctx)
8105 ext2_filsys fs = ctx->fs;
8107 struct ext2_inode inode;
8109 struct problem_context pctx;
8111 clear_problem_context(&pctx);
8113 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
8115 * If the root inode is not a directory, die here. The
8116 * user must have answered 'no' in pass1 when we
8117 * offered to clear it.
8119 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8121 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
8122 ctx->flags |= E2F_FLAG_ABORT;
8127 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
8128 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
8129 ctx->flags |= E2F_FLAG_ABORT;
8133 e2fsck_read_bitmaps(ctx);
8136 * First, find a free block
8138 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8140 pctx.str = "ext2fs_new_block";
8141 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8142 ctx->flags |= E2F_FLAG_ABORT;
8145 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8146 ext2fs_mark_block_bitmap(fs->block_map, blk);
8147 ext2fs_mark_bb_dirty(fs);
8150 * Now let's create the actual data block for the inode
8152 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
8155 pctx.str = "ext2fs_new_dir_block";
8156 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8157 ctx->flags |= E2F_FLAG_ABORT;
8161 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
8163 pctx.str = "ext2fs_write_dir_block";
8164 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8165 ctx->flags |= E2F_FLAG_ABORT;
8168 ext2fs_free_mem(&block);
8171 * Set up the inode structure
8173 memset(&inode, 0, sizeof(inode));
8174 inode.i_mode = 040755;
8175 inode.i_size = fs->blocksize;
8176 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8177 inode.i_links_count = 2;
8178 inode.i_blocks = fs->blocksize / 512;
8179 inode.i_block[0] = blk;
8182 * Write out the inode.
8184 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
8186 pctx.str = "ext2fs_write_inode";
8187 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8188 ctx->flags |= E2F_FLAG_ABORT;
8193 * Miscellaneous bookkeeping...
8195 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
8196 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
8197 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
8199 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
8200 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
8201 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
8202 ext2fs_mark_ib_dirty(fs);
8206 * This subroutine is responsible for making sure that a particular
8207 * directory is connected to the root; if it isn't we trace it up as
8208 * far as we can go, and then offer to connect the resulting parent to
8209 * the lost+found. We have to do loop detection; if we ever discover
8210 * a loop, we treat that as a disconnected directory and offer to
8211 * reparent it to lost+found.
8213 * However, loop detection is expensive, because for very large
8214 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
8215 * is non-trivial. Loops in filesystems are also a rare error case,
8216 * and we shouldn't optimize for error cases. So we try two passes of
8217 * the algorithm. The first time, we ignore loop detection and merely
8218 * increment a counter; if the counter exceeds some extreme threshold,
8219 * then we try again with the loop detection bitmap enabled.
8221 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8222 struct problem_context *pctx)
8224 ext2_filsys fs = ctx->fs;
8225 struct dir_info *p = dir;
8226 int loop_pass = 0, parent_count = 0;
8233 * Mark this inode as being "done"; by the time we
8234 * return from this function, the inode we either be
8235 * verified as being connected to the directory tree,
8236 * or we will have offered to reconnect this to
8239 * If it was marked done already, then we've reached a
8240 * parent we've already checked.
8242 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
8246 * If this directory doesn't have a parent, or we've
8247 * seen the parent once already, then offer to
8248 * reparent it to lost+found
8252 (ext2fs_test_inode_bitmap(inode_loop_detect,
8255 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
8256 if (e2fsck_reconnect_file(ctx, pctx->ino))
8257 ext2fs_unmark_valid(fs);
8259 p = e2fsck_get_dir_info(ctx, pctx->ino);
8260 p->parent = ctx->lost_and_found;
8261 fix_dotdot(ctx, p, ctx->lost_and_found);
8266 p = e2fsck_get_dir_info(ctx, p->parent);
8268 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
8272 ext2fs_mark_inode_bitmap(inode_loop_detect,
8274 } else if (parent_count++ > 2048) {
8276 * If we've run into a path depth that's
8277 * greater than 2048, try again with the inode
8278 * loop bitmap turned on and start from the
8282 if (inode_loop_detect)
8283 ext2fs_clear_inode_bitmap(inode_loop_detect);
8285 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
8286 if (pctx->errcode) {
8289 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
8290 ctx->flags |= E2F_FLAG_ABORT;
8299 * Make sure that .. and the parent directory are the same;
8300 * offer to fix it if not.
8302 if (dir->parent != dir->dotdot) {
8303 pctx->ino = dir->ino;
8304 pctx->ino2 = dir->dotdot;
8305 pctx->dir = dir->parent;
8306 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
8307 fix_dotdot(ctx, dir, dir->parent);
8313 * This routine gets the lost_and_found inode, making it a directory
8316 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
8318 ext2_filsys fs = ctx->fs;
8322 struct ext2_inode inode;
8324 static const char name[] = "lost+found";
8325 struct problem_context pctx;
8326 struct dir_info *dirinfo;
8328 if (ctx->lost_and_found)
8329 return ctx->lost_and_found;
8331 clear_problem_context(&pctx);
8333 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
8334 sizeof(name)-1, 0, &ino);
8338 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
8339 ctx->lost_and_found = ino;
8343 /* Lost+found isn't a directory! */
8347 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
8350 /* OK, unlink the old /lost+found file. */
8351 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
8353 pctx.str = "ext2fs_unlink";
8354 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8357 dirinfo = e2fsck_get_dir_info(ctx, ino);
8359 dirinfo->parent = 0;
8360 e2fsck_adjust_inode_count(ctx, ino, -1);
8361 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
8362 pctx.errcode = retval;
8363 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
8365 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
8369 * Read the inode and block bitmaps in; we'll be messing with
8372 e2fsck_read_bitmaps(ctx);
8375 * First, find a free block
8377 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8379 pctx.errcode = retval;
8380 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
8383 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8384 ext2fs_block_alloc_stats(fs, blk, +1);
8387 * Next find a free inode.
8389 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
8390 ctx->inode_used_map, &ino);
8392 pctx.errcode = retval;
8393 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
8396 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
8397 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
8398 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
8401 * Now let's create the actual data block for the inode
8403 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
8405 pctx.errcode = retval;
8406 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
8410 retval = ext2fs_write_dir_block(fs, blk, block);
8411 ext2fs_free_mem(&block);
8413 pctx.errcode = retval;
8414 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
8419 * Set up the inode structure
8421 memset(&inode, 0, sizeof(inode));
8422 inode.i_mode = 040700;
8423 inode.i_size = fs->blocksize;
8424 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8425 inode.i_links_count = 2;
8426 inode.i_blocks = fs->blocksize / 512;
8427 inode.i_block[0] = blk;
8430 * Next, write out the inode.
8432 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
8434 pctx.str = "ext2fs_write_inode";
8435 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8439 * Finally, create the directory link
8441 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
8443 pctx.str = "ext2fs_link";
8444 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8449 * Miscellaneous bookkeeping that needs to be kept straight.
8451 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
8452 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
8453 ext2fs_icount_store(ctx->inode_count, ino, 2);
8454 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
8455 ctx->lost_and_found = ino;
8460 * This routine will connect a file to lost+found
8462 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
8464 ext2_filsys fs = ctx->fs;
8467 struct problem_context pctx;
8468 struct ext2_inode inode;
8471 clear_problem_context(&pctx);
8474 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
8475 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
8476 ctx->bad_lost_and_found++;
8478 if (ctx->bad_lost_and_found) {
8479 fix_problem(ctx, PR_3_NO_LPF, &pctx);
8483 sprintf(name, "#%u", ino);
8484 if (ext2fs_read_inode(fs, ino, &inode) == 0)
8485 file_type = ext2_file_type(inode.i_mode);
8486 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
8487 if (retval == EXT2_ET_DIR_NO_SPACE) {
8488 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
8490 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
8493 pctx.errcode = retval;
8494 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
8497 retval = ext2fs_link(fs, ctx->lost_and_found, name,
8501 pctx.errcode = retval;
8502 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
8505 e2fsck_adjust_inode_count(ctx, ino, 1);
8511 * Utility routine to adjust the inode counts on an inode.
8513 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
8515 ext2_filsys fs = ctx->fs;
8517 struct ext2_inode inode;
8522 retval = ext2fs_read_inode(fs, ino, &inode);
8527 ext2fs_icount_increment(ctx->inode_count, ino, 0);
8528 if (inode.i_links_count == (__u16) ~0)
8530 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
8531 inode.i_links_count++;
8532 } else if (adj == -1) {
8533 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
8534 if (inode.i_links_count == 0)
8536 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
8537 inode.i_links_count--;
8540 retval = ext2fs_write_inode(fs, ino, &inode);
8548 * Fix parent --- this routine fixes up the parent of a directory.
8550 struct fix_dotdot_struct {
8557 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
8558 int offset FSCK_ATTR((unused)),
8559 int blocksize FSCK_ATTR((unused)),
8560 char *buf FSCK_ATTR((unused)),
8563 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
8565 struct problem_context pctx;
8567 if ((dirent->name_len & 0xFF) != 2)
8569 if (strncmp(dirent->name, "..", 2))
8572 clear_problem_context(&pctx);
8574 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
8576 pctx.errcode = retval;
8577 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
8579 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
8581 pctx.errcode = retval;
8582 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
8584 dirent->inode = fp->parent;
8587 return DIRENT_ABORT | DIRENT_CHANGED;
8590 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
8592 ext2_filsys fs = ctx->fs;
8594 struct fix_dotdot_struct fp;
8595 struct problem_context pctx;
8602 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
8603 0, fix_dotdot_proc, &fp);
8604 if (retval || !fp.done) {
8605 clear_problem_context(&pctx);
8606 pctx.ino = dir->ino;
8607 pctx.errcode = retval;
8608 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
8609 PR_3_FIX_PARENT_NOFIND, &pctx);
8610 ext2fs_unmark_valid(fs);
8612 dir->dotdot = parent;
8618 * These routines are responsible for expanding a /lost+found if it is
8622 struct expand_dir_struct {
8624 int guaranteed_size;
8631 static int expand_dir_proc(ext2_filsys fs,
8633 e2_blkcnt_t blockcnt,
8634 blk_t ref_block FSCK_ATTR((unused)),
8635 int ref_offset FSCK_ATTR((unused)),
8638 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
8640 static blk_t last_blk = 0;
8647 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
8651 es->last_block = blockcnt;
8653 last_blk = *blocknr;
8656 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
8663 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
8669 retval = ext2fs_write_dir_block(fs, new_blk, block);
8671 retval = ext2fs_get_mem(fs->blocksize, &block);
8676 memset(block, 0, fs->blocksize);
8677 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
8683 ext2fs_free_mem(&block);
8685 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
8686 ext2fs_block_alloc_stats(fs, new_blk, +1);
8690 return (BLOCK_CHANGED | BLOCK_ABORT);
8692 return BLOCK_CHANGED;
8695 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
8696 int num, int guaranteed_size)
8698 ext2_filsys fs = ctx->fs;
8700 struct expand_dir_struct es;
8701 struct ext2_inode inode;
8703 if (!(fs->flags & EXT2_FLAG_RW))
8704 return EXT2_ET_RO_FILSYS;
8707 * Read the inode and block bitmaps in; we'll be messing with
8710 e2fsck_read_bitmaps(ctx);
8712 retval = ext2fs_check_directory(fs, dir);
8717 es.guaranteed_size = guaranteed_size;
8723 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
8724 0, expand_dir_proc, &es);
8730 * Update the size and block count fields in the inode.
8732 retval = ext2fs_read_inode(fs, dir, &inode);
8736 inode.i_size = (es.last_block + 1) * fs->blocksize;
8737 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
8739 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
8745 * pass4.c -- pass #4 of e2fsck: Check reference counts
8747 * Pass 4 frees the following data structures:
8748 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
8749 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
8753 * This routine is called when an inode is not connected to the
8756 * This subroutine returns 1 then the caller shouldn't bother with the
8757 * rest of the pass 4 tests.
8759 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
8761 ext2_filsys fs = ctx->fs;
8762 struct ext2_inode inode;
8763 struct problem_context pctx;
8765 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
8766 clear_problem_context(&pctx);
8768 pctx.inode = &inode;
8771 * Offer to delete any zero-length files that does not have
8772 * blocks. If there is an EA block, it might have useful
8773 * information, so we won't prompt to delete it, but let it be
8774 * reconnected to lost+found.
8776 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
8777 LINUX_S_ISDIR(inode.i_mode))) {
8778 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
8779 ext2fs_icount_store(ctx->inode_link_info, i, 0);
8780 inode.i_links_count = 0;
8781 inode.i_dtime = time(0);
8782 e2fsck_write_inode(ctx, i, &inode,
8783 "disconnect_inode");
8785 * Fix up the bitmaps...
8787 e2fsck_read_bitmaps(ctx);
8788 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
8789 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
8790 ext2fs_inode_alloc_stats2(fs, i, -1,
8791 LINUX_S_ISDIR(inode.i_mode));
8797 * Prompt to reconnect.
8799 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
8800 if (e2fsck_reconnect_file(ctx, i))
8801 ext2fs_unmark_valid(fs);
8804 * If we don't attach the inode, then skip the
8805 * i_links_test since there's no point in trying to
8806 * force i_links_count to zero.
8808 ext2fs_unmark_valid(fs);
8815 static void e2fsck_pass4(e2fsck_t ctx)
8817 ext2_filsys fs = ctx->fs;
8819 struct ext2_inode inode;
8820 struct problem_context pctx;
8821 __u16 link_count, link_counted;
8823 int group, maxgroup;
8827 clear_problem_context(&pctx);
8829 if (!(ctx->options & E2F_OPT_PREEN))
8830 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
8833 maxgroup = fs->group_desc_count;
8835 if ((ctx->progress)(ctx, 4, 0, maxgroup))
8838 for (i=1; i <= fs->super->s_inodes_count; i++) {
8839 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8841 if ((i % fs->super->s_inodes_per_group) == 0) {
8844 if ((ctx->progress)(ctx, 4, group, maxgroup))
8847 if (i == EXT2_BAD_INO ||
8848 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
8850 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
8851 (ctx->inode_imagic_map &&
8852 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
8853 (ctx->inode_bb_map &&
8854 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
8856 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
8857 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
8858 if (link_counted == 0) {
8860 buf = e2fsck_allocate_memory(ctx,
8861 fs->blocksize, "bad_inode buffer");
8862 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
8864 if (disconnect_inode(ctx, i))
8866 ext2fs_icount_fetch(ctx->inode_link_info, i,
8868 ext2fs_icount_fetch(ctx->inode_count, i,
8871 if (link_counted != link_count) {
8872 e2fsck_read_inode(ctx, i, &inode, "pass4");
8874 pctx.inode = &inode;
8875 if (link_count != inode.i_links_count) {
8876 pctx.num = link_count;
8878 PR_4_INCONSISTENT_COUNT, &pctx);
8880 pctx.num = link_counted;
8881 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
8882 inode.i_links_count = link_counted;
8883 e2fsck_write_inode(ctx, i, &inode, "pass4");
8887 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
8888 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
8889 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
8890 ctx->inode_bb_map = 0;
8891 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
8892 ctx->inode_imagic_map = 0;
8893 ext2fs_free_mem(&buf);
8897 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
8900 #define NO_BLK ((blk_t) -1)
8902 static void print_bitmap_problem(e2fsck_t ctx, int problem,
8903 struct problem_context *pctx)
8906 case PR_5_BLOCK_UNUSED:
8907 if (pctx->blk == pctx->blk2)
8910 problem = PR_5_BLOCK_RANGE_UNUSED;
8912 case PR_5_BLOCK_USED:
8913 if (pctx->blk == pctx->blk2)
8916 problem = PR_5_BLOCK_RANGE_USED;
8918 case PR_5_INODE_UNUSED:
8919 if (pctx->ino == pctx->ino2)
8922 problem = PR_5_INODE_RANGE_UNUSED;
8924 case PR_5_INODE_USED:
8925 if (pctx->ino == pctx->ino2)
8928 problem = PR_5_INODE_RANGE_USED;
8931 fix_problem(ctx, problem, pctx);
8932 pctx->blk = pctx->blk2 = NO_BLK;
8933 pctx->ino = pctx->ino2 = 0;
8936 static void check_block_bitmaps(e2fsck_t ctx)
8938 ext2_filsys fs = ctx->fs;
8942 unsigned int blocks = 0;
8943 unsigned int free_blocks = 0;
8946 struct problem_context pctx;
8947 int problem, save_problem, fixit, had_problem;
8950 clear_problem_context(&pctx);
8951 free_array = (int *) e2fsck_allocate_memory(ctx,
8952 fs->group_desc_count * sizeof(int), "free block count array");
8954 if ((fs->super->s_first_data_block <
8955 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
8956 (fs->super->s_blocks_count-1 >
8957 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
8959 pctx.blk = fs->super->s_first_data_block;
8960 pctx.blk2 = fs->super->s_blocks_count -1;
8961 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
8962 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
8963 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8965 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8969 if ((fs->super->s_first_data_block <
8970 ext2fs_get_block_bitmap_start(fs->block_map)) ||
8971 (fs->super->s_blocks_count-1 >
8972 ext2fs_get_block_bitmap_end(fs->block_map))) {
8974 pctx.blk = fs->super->s_first_data_block;
8975 pctx.blk2 = fs->super->s_blocks_count -1;
8976 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
8977 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
8978 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8980 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8987 pctx.blk = pctx.blk2 = NO_BLK;
8988 for (i = fs->super->s_first_data_block;
8989 i < fs->super->s_blocks_count;
8991 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
8992 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
8994 if (actual == bitmap)
8997 if (!actual && bitmap) {
8999 * Block not used, but marked in use in the bitmap.
9001 problem = PR_5_BLOCK_UNUSED;
9004 * Block used, but not marked in use in the bitmap.
9006 problem = PR_5_BLOCK_USED;
9008 if (pctx.blk == NO_BLK) {
9009 pctx.blk = pctx.blk2 = i;
9010 save_problem = problem;
9012 if ((problem == save_problem) &&
9016 print_bitmap_problem(ctx, save_problem, &pctx);
9017 pctx.blk = pctx.blk2 = i;
9018 save_problem = problem;
9021 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9030 if ((blocks == fs->super->s_blocks_per_group) ||
9031 (i == fs->super->s_blocks_count-1)) {
9032 free_array[group] = group_free;
9037 if ((ctx->progress)(ctx, 5, group,
9038 fs->group_desc_count*2))
9042 if (pctx.blk != NO_BLK)
9043 print_bitmap_problem(ctx, save_problem, &pctx);
9045 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
9048 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9051 ext2fs_free_block_bitmap(fs->block_map);
9052 retval = ext2fs_copy_bitmap(ctx->block_found_map,
9055 clear_problem_context(&pctx);
9056 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
9057 ctx->flags |= E2F_FLAG_ABORT;
9060 ext2fs_set_bitmap_padding(fs->block_map);
9061 ext2fs_mark_bb_dirty(fs);
9063 /* Redo the counts */
9064 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
9065 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9067 } else if (fixit == 0)
9068 ext2fs_unmark_valid(fs);
9070 for (i = 0; i < fs->group_desc_count; i++) {
9071 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
9073 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
9074 pctx.blk2 = free_array[i];
9076 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
9078 fs->group_desc[i].bg_free_blocks_count =
9080 ext2fs_mark_super_dirty(fs);
9082 ext2fs_unmark_valid(fs);
9085 if (free_blocks != fs->super->s_free_blocks_count) {
9087 pctx.blk = fs->super->s_free_blocks_count;
9088 pctx.blk2 = free_blocks;
9090 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
9091 fs->super->s_free_blocks_count = free_blocks;
9092 ext2fs_mark_super_dirty(fs);
9094 ext2fs_unmark_valid(fs);
9096 ext2fs_free_mem(&free_array);
9099 static void check_inode_bitmaps(e2fsck_t ctx)
9101 ext2_filsys fs = ctx->fs;
9103 unsigned int free_inodes = 0;
9107 unsigned int inodes = 0;
9112 struct problem_context pctx;
9113 int problem, save_problem, fixit, had_problem;
9115 clear_problem_context(&pctx);
9116 free_array = (int *) e2fsck_allocate_memory(ctx,
9117 fs->group_desc_count * sizeof(int), "free inode count array");
9119 dir_array = (int *) e2fsck_allocate_memory(ctx,
9120 fs->group_desc_count * sizeof(int), "directory count array");
9122 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
9123 (fs->super->s_inodes_count >
9124 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
9127 pctx.blk2 = fs->super->s_inodes_count;
9128 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
9129 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
9130 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9132 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9135 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
9136 (fs->super->s_inodes_count >
9137 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
9140 pctx.blk2 = fs->super->s_inodes_count;
9141 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
9142 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
9143 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9145 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9152 pctx.ino = pctx.ino2 = 0;
9153 for (i = 1; i <= fs->super->s_inodes_count; i++) {
9154 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
9155 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
9157 if (actual == bitmap)
9160 if (!actual && bitmap) {
9162 * Inode wasn't used, but marked in bitmap
9164 problem = PR_5_INODE_UNUSED;
9165 } else /* if (actual && !bitmap) */ {
9167 * Inode used, but not in bitmap
9169 problem = PR_5_INODE_USED;
9171 if (pctx.ino == 0) {
9172 pctx.ino = pctx.ino2 = i;
9173 save_problem = problem;
9175 if ((problem == save_problem) &&
9179 print_bitmap_problem(ctx, save_problem, &pctx);
9180 pctx.ino = pctx.ino2 = i;
9181 save_problem = problem;
9184 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9192 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
9196 if ((inodes == fs->super->s_inodes_per_group) ||
9197 (i == fs->super->s_inodes_count)) {
9198 free_array[group] = group_free;
9199 dir_array[group] = dirs_count;
9205 if ((ctx->progress)(ctx, 5,
9206 group + fs->group_desc_count,
9207 fs->group_desc_count*2))
9212 print_bitmap_problem(ctx, save_problem, &pctx);
9215 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
9218 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9221 ext2fs_free_inode_bitmap(fs->inode_map);
9222 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
9225 clear_problem_context(&pctx);
9226 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
9227 ctx->flags |= E2F_FLAG_ABORT;
9230 ext2fs_set_bitmap_padding(fs->inode_map);
9231 ext2fs_mark_ib_dirty(fs);
9234 inodes = 0; free_inodes = 0; group_free = 0;
9235 dirs_count = 0; group = 0;
9236 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9237 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
9239 } else if (fixit == 0)
9240 ext2fs_unmark_valid(fs);
9242 for (i = 0; i < fs->group_desc_count; i++) {
9243 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
9245 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
9246 pctx.ino2 = free_array[i];
9247 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
9249 fs->group_desc[i].bg_free_inodes_count =
9251 ext2fs_mark_super_dirty(fs);
9253 ext2fs_unmark_valid(fs);
9255 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
9257 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
9258 pctx.ino2 = dir_array[i];
9260 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
9262 fs->group_desc[i].bg_used_dirs_count =
9264 ext2fs_mark_super_dirty(fs);
9266 ext2fs_unmark_valid(fs);
9269 if (free_inodes != fs->super->s_free_inodes_count) {
9271 pctx.ino = fs->super->s_free_inodes_count;
9272 pctx.ino2 = free_inodes;
9274 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
9275 fs->super->s_free_inodes_count = free_inodes;
9276 ext2fs_mark_super_dirty(fs);
9278 ext2fs_unmark_valid(fs);
9280 ext2fs_free_mem(&free_array);
9281 ext2fs_free_mem(&dir_array);
9284 static void check_inode_end(e2fsck_t ctx)
9286 ext2_filsys fs = ctx->fs;
9287 ext2_ino_t end, save_inodes_count, i;
9288 struct problem_context pctx;
9290 clear_problem_context(&pctx);
9292 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
9293 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
9294 &save_inodes_count);
9297 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9298 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9301 if (save_inodes_count == end)
9304 for (i = save_inodes_count + 1; i <= end; i++) {
9305 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
9306 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
9307 for (i = save_inodes_count + 1; i <= end; i++)
9308 ext2fs_mark_inode_bitmap(fs->inode_map,
9310 ext2fs_mark_ib_dirty(fs);
9312 ext2fs_unmark_valid(fs);
9317 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
9318 save_inodes_count, 0);
9321 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9322 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9327 static void check_block_end(e2fsck_t ctx)
9329 ext2_filsys fs = ctx->fs;
9330 blk_t end, save_blocks_count, i;
9331 struct problem_context pctx;
9333 clear_problem_context(&pctx);
9335 end = fs->block_map->start +
9336 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
9337 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
9338 &save_blocks_count);
9341 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9342 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9345 if (save_blocks_count == end)
9348 for (i = save_blocks_count + 1; i <= end; i++) {
9349 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
9350 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
9351 for (i = save_blocks_count + 1; i <= end; i++)
9352 ext2fs_mark_block_bitmap(fs->block_map,
9354 ext2fs_mark_bb_dirty(fs);
9356 ext2fs_unmark_valid(fs);
9361 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
9362 save_blocks_count, 0);
9365 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9366 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9371 static void e2fsck_pass5(e2fsck_t ctx)
9373 struct problem_context pctx;
9377 clear_problem_context(&pctx);
9379 if (!(ctx->options & E2F_OPT_PREEN))
9380 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
9383 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
9386 e2fsck_read_bitmaps(ctx);
9388 check_block_bitmaps(ctx);
9389 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9391 check_inode_bitmaps(ctx);
9392 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9394 check_inode_end(ctx);
9395 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9397 check_block_end(ctx);
9398 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9401 ext2fs_free_inode_bitmap(ctx->inode_used_map);
9402 ctx->inode_used_map = 0;
9403 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
9404 ctx->inode_dir_map = 0;
9405 ext2fs_free_block_bitmap(ctx->block_found_map);
9406 ctx->block_found_map = 0;
9410 * problem.c --- report filesystem problems to the user
9413 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
9414 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
9415 #define PR_NO_DEFAULT 0x000004 /* Default to no */
9416 #define PR_MSG_ONLY 0x000008 /* Print message only */
9418 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
9420 #define PR_FATAL 0x001000 /* Fatal error */
9421 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
9423 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
9424 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
9425 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
9426 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
9427 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
9430 #define PROMPT_NONE 0
9431 #define PROMPT_FIX 1
9432 #define PROMPT_CLEAR 2
9433 #define PROMPT_RELOCATE 3
9434 #define PROMPT_ALLOCATE 4
9435 #define PROMPT_EXPAND 5
9436 #define PROMPT_CONNECT 6
9437 #define PROMPT_CREATE 7
9438 #define PROMPT_SALVAGE 8
9439 #define PROMPT_TRUNCATE 9
9440 #define PROMPT_CLEAR_INODE 10
9441 #define PROMPT_ABORT 11
9442 #define PROMPT_SPLIT 12
9443 #define PROMPT_CONTINUE 13
9444 #define PROMPT_CLONE 14
9445 #define PROMPT_DELETE 15
9446 #define PROMPT_SUPPRESS 16
9447 #define PROMPT_UNLINK 17
9448 #define PROMPT_CLEAR_HTREE 18
9449 #define PROMPT_RECREATE 19
9450 #define PROMPT_NULL 20
9452 struct e2fsck_problem {
9454 const char * e2p_description;
9457 problem_t second_code;
9460 struct latch_descr {
9463 problem_t end_message;
9468 * These are the prompts which are used to ask the user if they want
9471 static const char * const prompt[] = {
9472 N_("(no prompt)"), /* 0 */
9474 N_("Clear"), /* 2 */
9475 N_("Relocate"), /* 3 */
9476 N_("Allocate"), /* 4 */
9477 N_("Expand"), /* 5 */
9478 N_("Connect to /lost+found"), /* 6 */
9479 N_("Create"), /* 7 */
9480 N_("Salvage"), /* 8 */
9481 N_("Truncate"), /* 9 */
9482 N_("Clear inode"), /* 10 */
9483 N_("Abort"), /* 11 */
9484 N_("Split"), /* 12 */
9485 N_("Continue"), /* 13 */
9486 N_("Clone multiply-claimed blocks"), /* 14 */
9487 N_("Delete file"), /* 15 */
9488 N_("Suppress messages"),/* 16 */
9489 N_("Unlink"), /* 17 */
9490 N_("Clear HTree index"),/* 18 */
9491 N_("Recreate"), /* 19 */
9496 * These messages are printed when we are preen mode and we will be
9497 * automatically fixing the problem.
9499 static const char * const preen_msg[] = {
9500 N_("(NONE)"), /* 0 */
9501 N_("FIXED"), /* 1 */
9502 N_("CLEARED"), /* 2 */
9503 N_("RELOCATED"), /* 3 */
9504 N_("ALLOCATED"), /* 4 */
9505 N_("EXPANDED"), /* 5 */
9506 N_("RECONNECTED"), /* 6 */
9507 N_("CREATED"), /* 7 */
9508 N_("SALVAGED"), /* 8 */
9509 N_("TRUNCATED"), /* 9 */
9510 N_("INODE CLEARED"), /* 10 */
9511 N_("ABORTED"), /* 11 */
9512 N_("SPLIT"), /* 12 */
9513 N_("CONTINUING"), /* 13 */
9514 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
9515 N_("FILE DELETED"), /* 15 */
9516 N_("SUPPRESSED"), /* 16 */
9517 N_("UNLINKED"), /* 17 */
9518 N_("HTREE INDEX CLEARED"),/* 18 */
9519 N_("WILL RECREATE"), /* 19 */
9523 static const struct e2fsck_problem problem_table[] = {
9525 /* Pre-Pass 1 errors */
9527 /* Block bitmap not in group */
9528 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
9529 PROMPT_RELOCATE, PR_LATCH_RELOC },
9531 /* Inode bitmap not in group */
9532 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
9533 PROMPT_RELOCATE, PR_LATCH_RELOC },
9535 /* Inode table not in group */
9536 { PR_0_ITABLE_NOT_GROUP,
9537 N_("@i table for @g %g is not in @g. (@b %b)\n"
9538 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
9539 PROMPT_RELOCATE, PR_LATCH_RELOC },
9541 /* Superblock corrupt */
9543 N_("\nThe @S could not be read or does not describe a correct ext2\n"
9544 "@f. If the @v is valid and it really contains an ext2\n"
9545 "@f (and not swap or ufs or something else), then the @S\n"
9546 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
9547 " e2fsck -b %S <@v>\n\n"),
9548 PROMPT_NONE, PR_FATAL },
9550 /* Filesystem size is wrong */
9551 { PR_0_FS_SIZE_WRONG,
9552 N_("The @f size (according to the @S) is %b @bs\n"
9553 "The physical size of the @v is %c @bs\n"
9554 "Either the @S or the partition table is likely to be corrupt!\n"),
9557 /* Fragments not supported */
9558 { PR_0_NO_FRAGMENTS,
9559 N_("@S @b_size = %b, fragsize = %c.\n"
9560 "This version of e2fsck does not support fragment sizes different\n"
9561 "from the @b size.\n"),
9562 PROMPT_NONE, PR_FATAL },
9564 /* Bad blocks_per_group */
9565 { PR_0_BLOCKS_PER_GROUP,
9566 N_("@S @bs_per_group = %b, should have been %c\n"),
9567 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9569 /* Bad first_data_block */
9570 { PR_0_FIRST_DATA_BLOCK,
9571 N_("@S first_data_@b = %b, should have been %c\n"),
9572 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9574 /* Adding UUID to filesystem */
9576 N_("@f did not have a UUID; generating one.\n\n"),
9580 { PR_0_RELOCATE_HINT,
9581 N_("Note: if several inode or block bitmap blocks or part\n"
9582 "of the inode table require relocation, you may wish to try\n"
9583 "running e2fsck with the '-b %S' option first. The problem\n"
9584 "may lie only with the primary block group descriptors, and\n"
9585 "the backup block group descriptors may be OK.\n\n"),
9586 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
9588 /* Miscellaneous superblock corruption */
9589 { PR_0_MISC_CORRUPT_SUPER,
9590 N_("Corruption found in @S. (%s = %N).\n"),
9591 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9593 /* Error determing physical device size of filesystem */
9594 { PR_0_GETSIZE_ERROR,
9595 N_("Error determining size of the physical @v: %m\n"),
9596 PROMPT_NONE, PR_FATAL },
9598 /* Inode count in superblock is incorrect */
9599 { PR_0_INODE_COUNT_WRONG,
9600 N_("@i count in @S is %i, @s %j.\n"),
9603 { PR_0_HURD_CLEAR_FILETYPE,
9604 N_("The Hurd does not support the filetype feature.\n"),
9607 /* Journal inode is invalid */
9608 { PR_0_JOURNAL_BAD_INODE,
9609 N_("@S has an @n ext3 @j (@i %i).\n"),
9610 PROMPT_CLEAR, PR_PREEN_OK },
9612 /* The external journal has (unsupported) multiple filesystems */
9613 { PR_0_JOURNAL_UNSUPP_MULTIFS,
9614 N_("External @j has multiple @f users (unsupported).\n"),
9615 PROMPT_NONE, PR_FATAL },
9617 /* Can't find external journal */
9618 { PR_0_CANT_FIND_JOURNAL,
9619 N_("Can't find external @j\n"),
9620 PROMPT_NONE, PR_FATAL },
9622 /* External journal has bad superblock */
9623 { PR_0_EXT_JOURNAL_BAD_SUPER,
9624 N_("External @j has bad @S\n"),
9625 PROMPT_NONE, PR_FATAL },
9627 /* Superblock has a bad journal UUID */
9628 { PR_0_JOURNAL_BAD_UUID,
9629 N_("External @j does not support this @f\n"),
9630 PROMPT_NONE, PR_FATAL },
9632 /* Journal has an unknown superblock type */
9633 { PR_0_JOURNAL_UNSUPP_SUPER,
9634 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
9635 "It is likely that your copy of e2fsck is old and/or doesn't "
9636 "support this @j format.\n"
9637 "It is also possible the @j @S is corrupt.\n"),
9638 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
9640 /* Journal superblock is corrupt */
9641 { PR_0_JOURNAL_BAD_SUPER,
9642 N_("Ext3 @j @S is corrupt.\n"),
9643 PROMPT_FIX, PR_PREEN_OK },
9645 /* Superblock flag should be cleared */
9646 { PR_0_JOURNAL_HAS_JOURNAL,
9647 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
9648 PROMPT_CLEAR, PR_PREEN_OK },
9650 /* Superblock flag is incorrect */
9651 { PR_0_JOURNAL_RECOVER_SET,
9652 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
9653 PROMPT_CLEAR, PR_PREEN_OK },
9655 /* Journal has data, but recovery flag is clear */
9656 { PR_0_JOURNAL_RECOVERY_CLEAR,
9657 N_("ext3 recovery flag is clear, but @j has data.\n"),
9660 /* Ask if we should clear the journal */
9661 { PR_0_JOURNAL_RESET_JOURNAL,
9663 PROMPT_NULL, PR_PREEN_NOMSG },
9665 /* Ask if we should run the journal anyway */
9667 N_("Run @j anyway"),
9670 /* Run the journal by default */
9671 { PR_0_JOURNAL_RUN_DEFAULT,
9672 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
9675 /* Clearing orphan inode */
9676 { PR_0_ORPHAN_CLEAR_INODE,
9677 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
9680 /* Illegal block found in orphaned inode */
9681 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
9682 N_("@I @b #%B (%b) found in @o @i %i.\n"),
9685 /* Already cleared block found in orphaned inode */
9686 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
9687 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
9690 /* Illegal orphan inode in superblock */
9691 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
9692 N_("@I @o @i %i in @S.\n"),
9695 /* Illegal inode in orphaned inode list */
9696 { PR_0_ORPHAN_ILLEGAL_INODE,
9697 N_("@I @i %i in @o @i list.\n"),
9700 /* Filesystem revision is 0, but feature flags are set */
9701 { PR_0_FS_REV_LEVEL,
9702 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
9703 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9705 /* Journal superblock has an unknown read-only feature flag set */
9706 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
9707 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
9710 /* Journal superblock has an unknown incompatible feature flag set */
9711 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
9712 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
9715 /* Journal has unsupported version number */
9716 { PR_0_JOURNAL_UNSUPP_VERSION,
9717 N_("@j version not supported by this e2fsck.\n"),
9720 /* Moving journal to hidden file */
9721 { PR_0_MOVE_JOURNAL,
9722 N_("Moving @j from /%s to hidden @i.\n\n"),
9725 /* Error moving journal to hidden file */
9726 { PR_0_ERR_MOVE_JOURNAL,
9727 N_("Error moving @j: %m\n\n"),
9730 /* Clearing V2 journal superblock */
9731 { PR_0_CLEAR_V2_JOURNAL,
9732 N_("Found @n V2 @j @S fields (from V1 @j).\n"
9733 "Clearing fields beyond the V1 @j @S...\n\n"),
9736 /* Backup journal inode blocks */
9738 N_("Backing up @j @i @b information.\n\n"),
9741 /* Reserved blocks w/o resize_inode */
9742 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
9743 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
9744 "is %N; @s zero. "),
9747 /* Resize_inode not enabled, but resize inode is non-zero */
9748 { PR_0_CLEAR_RESIZE_INODE,
9749 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
9752 /* Resize inode invalid */
9753 { PR_0_RESIZE_INODE_INVALID,
9754 N_("Resize @i not valid. "),
9755 PROMPT_RECREATE, 0 },
9759 /* Pass 1: Checking inodes, blocks, and sizes */
9761 N_("Pass 1: Checking @is, @bs, and sizes\n"),
9764 /* Root directory is not an inode */
9765 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
9768 /* Root directory has dtime set */
9770 N_("@r has dtime set (probably due to old mke2fs). "),
9771 PROMPT_FIX, PR_PREEN_OK },
9773 /* Reserved inode has bad mode */
9774 { PR_1_RESERVED_BAD_MODE,
9775 N_("Reserved @i %i (%Q) has @n mode. "),
9776 PROMPT_CLEAR, PR_PREEN_OK },
9778 /* Deleted inode has zero dtime */
9780 N_("@D @i %i has zero dtime. "),
9781 PROMPT_FIX, PR_PREEN_OK },
9783 /* Inode in use, but dtime set */
9785 N_("@i %i is in use, but has dtime set. "),
9786 PROMPT_FIX, PR_PREEN_OK },
9788 /* Zero-length directory */
9789 { PR_1_ZERO_LENGTH_DIR,
9790 N_("@i %i is a @z @d. "),
9791 PROMPT_CLEAR, PR_PREEN_OK },
9793 /* Block bitmap conflicts with some other fs block */
9795 N_("@g %g's @b @B at %b @C.\n"),
9796 PROMPT_RELOCATE, 0 },
9798 /* Inode bitmap conflicts with some other fs block */
9800 N_("@g %g's @i @B at %b @C.\n"),
9801 PROMPT_RELOCATE, 0 },
9803 /* Inode table conflicts with some other fs block */
9804 { PR_1_ITABLE_CONFLICT,
9805 N_("@g %g's @i table at %b @C.\n"),
9806 PROMPT_RELOCATE, 0 },
9808 /* Block bitmap is on a bad block */
9809 { PR_1_BB_BAD_BLOCK,
9810 N_("@g %g's @b @B (%b) is bad. "),
9811 PROMPT_RELOCATE, 0 },
9813 /* Inode bitmap is on a bad block */
9814 { PR_1_IB_BAD_BLOCK,
9815 N_("@g %g's @i @B (%b) is bad. "),
9816 PROMPT_RELOCATE, 0 },
9818 /* Inode has incorrect i_size */
9820 N_("@i %i, i_size is %Is, @s %N. "),
9821 PROMPT_FIX, PR_PREEN_OK },
9823 /* Inode has incorrect i_blocks */
9824 { PR_1_BAD_I_BLOCKS,
9825 N_("@i %i, i_@bs is %Ib, @s %N. "),
9826 PROMPT_FIX, PR_PREEN_OK },
9828 /* Illegal blocknumber in inode */
9829 { PR_1_ILLEGAL_BLOCK_NUM,
9830 N_("@I @b #%B (%b) in @i %i. "),
9831 PROMPT_CLEAR, PR_LATCH_BLOCK },
9833 /* Block number overlaps fs metadata */
9834 { PR_1_BLOCK_OVERLAPS_METADATA,
9835 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
9836 PROMPT_CLEAR, PR_LATCH_BLOCK },
9838 /* Inode has illegal blocks (latch question) */
9839 { PR_1_INODE_BLOCK_LATCH,
9840 N_("@i %i has illegal @b(s). "),
9843 /* Too many bad blocks in inode */
9844 { PR_1_TOO_MANY_BAD_BLOCKS,
9845 N_("Too many illegal @bs in @i %i.\n"),
9846 PROMPT_CLEAR_INODE, PR_NO_OK },
9848 /* Illegal block number in bad block inode */
9849 { PR_1_BB_ILLEGAL_BLOCK_NUM,
9850 N_("@I @b #%B (%b) in bad @b @i. "),
9851 PROMPT_CLEAR, PR_LATCH_BBLOCK },
9853 /* Bad block inode has illegal blocks (latch question) */
9854 { PR_1_INODE_BBLOCK_LATCH,
9855 N_("Bad @b @i has illegal @b(s). "),
9858 /* Duplicate or bad blocks in use! */
9859 { PR_1_DUP_BLOCKS_PREENSTOP,
9860 N_("Duplicate or bad @b in use!\n"),
9863 /* Bad block used as bad block indirect block */
9864 { PR_1_BBINODE_BAD_METABLOCK,
9865 N_("Bad @b %b used as bad @b @i indirect @b. "),
9866 PROMPT_CLEAR, PR_LATCH_BBLOCK },
9868 /* Inconsistency can't be fixed prompt */
9869 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
9870 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
9871 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
9873 PROMPT_CONTINUE, PR_PREEN_NOMSG },
9875 /* Bad primary block */
9876 { PR_1_BAD_PRIMARY_BLOCK,
9877 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
9878 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
9880 /* Bad primary block prompt */
9881 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
9882 N_("You can remove this @b from the bad @b list and hope\n"
9883 "that the @b is really OK. But there are no guarantees.\n\n"),
9884 PROMPT_CLEAR, PR_PREEN_NOMSG },
9886 /* Bad primary superblock */
9887 { PR_1_BAD_PRIMARY_SUPERBLOCK,
9888 N_("The primary @S (%b) is on the bad @b list.\n"),
9889 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9891 /* Bad primary block group descriptors */
9892 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
9893 N_("Block %b in the primary @g descriptors "
9894 "is on the bad @b list\n"),
9895 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9897 /* Bad superblock in group */
9898 { PR_1_BAD_SUPERBLOCK,
9899 N_("Warning: Group %g's @S (%b) is bad.\n"),
9900 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9902 /* Bad block group descriptors in group */
9903 { PR_1_BAD_GROUP_DESCRIPTORS,
9904 N_("Warning: Group %g's copy of the @g descriptors has a bad "
9906 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9908 /* Block claimed for no reason */
9909 { PR_1_PROGERR_CLAIMED_BLOCK,
9910 N_("Programming error? @b #%b claimed for no reason in "
9911 "process_bad_@b.\n"),
9912 PROMPT_NONE, PR_PREEN_OK },
9914 /* Error allocating blocks for relocating metadata */
9915 { PR_1_RELOC_BLOCK_ALLOCATE,
9916 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
9917 PROMPT_NONE, PR_PREEN_OK },
9919 /* Error allocating block buffer during relocation process */
9920 { PR_1_RELOC_MEMORY_ALLOCATE,
9921 N_("@A @b buffer for relocating %s\n"),
9922 PROMPT_NONE, PR_PREEN_OK },
9924 /* Relocating metadata group information from X to Y */
9925 { PR_1_RELOC_FROM_TO,
9926 N_("Relocating @g %g's %s from %b to %c...\n"),
9927 PROMPT_NONE, PR_PREEN_OK },
9929 /* Relocating metatdata group information to X */
9931 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
9932 PROMPT_NONE, PR_PREEN_OK },
9934 /* Block read error during relocation process */
9935 { PR_1_RELOC_READ_ERR,
9936 N_("Warning: could not read @b %b of %s: %m\n"),
9937 PROMPT_NONE, PR_PREEN_OK },
9939 /* Block write error during relocation process */
9940 { PR_1_RELOC_WRITE_ERR,
9941 N_("Warning: could not write @b %b for %s: %m\n"),
9942 PROMPT_NONE, PR_PREEN_OK },
9944 /* Error allocating inode bitmap */
9945 { PR_1_ALLOCATE_IBITMAP_ERROR,
9946 N_("@A @i @B (%N): %m\n"),
9947 PROMPT_NONE, PR_FATAL },
9949 /* Error allocating block bitmap */
9950 { PR_1_ALLOCATE_BBITMAP_ERROR,
9951 N_("@A @b @B (%N): %m\n"),
9952 PROMPT_NONE, PR_FATAL },
9954 /* Error allocating icount structure */
9955 { PR_1_ALLOCATE_ICOUNT,
9956 N_("@A icount link information: %m\n"),
9957 PROMPT_NONE, PR_FATAL },
9959 /* Error allocating dbcount */
9960 { PR_1_ALLOCATE_DBCOUNT,
9961 N_("@A @d @b array: %m\n"),
9962 PROMPT_NONE, PR_FATAL },
9964 /* Error while scanning inodes */
9966 N_("Error while scanning @is (%i): %m\n"),
9967 PROMPT_NONE, PR_FATAL },
9969 /* Error while iterating over blocks */
9970 { PR_1_BLOCK_ITERATE,
9971 N_("Error while iterating over @bs in @i %i: %m\n"),
9972 PROMPT_NONE, PR_FATAL },
9974 /* Error while storing inode count information */
9975 { PR_1_ICOUNT_STORE,
9976 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
9977 PROMPT_NONE, PR_FATAL },
9979 /* Error while storing directory block information */
9981 N_("Error storing @d @b information "
9982 "(@i=%i, @b=%b, num=%N): %m\n"),
9983 PROMPT_NONE, PR_FATAL },
9985 /* Error while reading inode (for clearing) */
9987 N_("Error reading @i %i: %m\n"),
9988 PROMPT_NONE, PR_FATAL },
9990 /* Suppress messages prompt */
9991 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
9993 /* Imagic flag set on an inode when filesystem doesn't support it */
9995 N_("@i %i has imagic flag set. "),
9998 /* Immutable flag set on a device or socket inode */
9999 { PR_1_SET_IMMUTABLE,
10000 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
10001 "or append-only flag set. "),
10002 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
10004 /* Compression flag set on an inode when filesystem doesn't support it */
10006 N_("@i %i has @cion flag set on @f without @cion support. "),
10009 /* Non-zero size for device, fifo or socket inode */
10010 { PR_1_SET_NONZSIZE,
10011 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
10012 PROMPT_FIX, PR_PREEN_OK },
10014 /* Filesystem revision is 0, but feature flags are set */
10015 { PR_1_FS_REV_LEVEL,
10016 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
10017 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10019 /* Journal inode is not in use, but contains data */
10020 { PR_1_JOURNAL_INODE_NOT_CLEAR,
10021 N_("@j @i is not in use, but contains data. "),
10022 PROMPT_CLEAR, PR_PREEN_OK },
10024 /* Journal has bad mode */
10025 { PR_1_JOURNAL_BAD_MODE,
10026 N_("@j is not regular file. "),
10027 PROMPT_FIX, PR_PREEN_OK },
10029 /* Deal with inodes that were part of orphan linked list */
10031 N_("@i %i was part of the @o @i list. "),
10032 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
10034 /* Deal with inodes that were part of corrupted orphan linked
10035 list (latch question) */
10036 { PR_1_ORPHAN_LIST_REFUGEES,
10037 N_("@is that were part of a corrupted orphan linked list found. "),
10040 /* Error allocating refcount structure */
10041 { PR_1_ALLOCATE_REFCOUNT,
10042 N_("@A refcount structure (%N): %m\n"),
10043 PROMPT_NONE, PR_FATAL },
10045 /* Error reading extended attribute block */
10046 { PR_1_READ_EA_BLOCK,
10047 N_("Error reading @a @b %b for @i %i. "),
10050 /* Invalid extended attribute block */
10051 { PR_1_BAD_EA_BLOCK,
10052 N_("@i %i has a bad @a @b %b. "),
10055 /* Error reading Extended Attribute block while fixing refcount */
10056 { PR_1_EXTATTR_READ_ABORT,
10057 N_("Error reading @a @b %b (%m). "),
10060 /* Extended attribute reference count incorrect */
10061 { PR_1_EXTATTR_REFCOUNT,
10062 N_("@a @b %b has reference count %B, @s %N. "),
10065 /* Error writing Extended Attribute block while fixing refcount */
10066 { PR_1_EXTATTR_WRITE,
10067 N_("Error writing @a @b %b (%m). "),
10070 /* Multiple EA blocks not supported */
10071 { PR_1_EA_MULTI_BLOCK,
10072 N_("@a @b %b has h_@bs > 1. "),
10075 /* Error allocating EA region allocation structure */
10076 { PR_1_EA_ALLOC_REGION,
10077 N_("@A @a @b %b. "),
10080 /* Error EA allocation collision */
10081 { PR_1_EA_ALLOC_COLLISION,
10082 N_("@a @b %b is corrupt (allocation collision). "),
10085 /* Bad extended attribute name */
10086 { PR_1_EA_BAD_NAME,
10087 N_("@a @b %b is corrupt (@n name). "),
10090 /* Bad extended attribute value */
10091 { PR_1_EA_BAD_VALUE,
10092 N_("@a @b %b is corrupt (@n value). "),
10095 /* Inode too big (latch question) */
10096 { PR_1_INODE_TOOBIG,
10097 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
10099 /* Directory too big */
10101 N_("@b #%B (%b) causes @d to be too big. "),
10102 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10104 /* Regular file too big */
10106 N_("@b #%B (%b) causes file to be too big. "),
10107 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10109 /* Symlink too big */
10110 { PR_1_TOOBIG_SYMLINK,
10111 N_("@b #%B (%b) causes symlink to be too big. "),
10112 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10114 /* INDEX_FL flag set on a non-HTREE filesystem */
10116 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
10117 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10119 /* INDEX_FL flag set on a non-directory */
10120 { PR_1_HTREE_NODIR,
10121 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
10122 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10124 /* Invalid root node in HTREE directory */
10125 { PR_1_HTREE_BADROOT,
10126 N_("@h %i has an @n root node.\n"),
10127 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10129 /* Unsupported hash version in HTREE directory */
10130 { PR_1_HTREE_HASHV,
10131 N_("@h %i has an unsupported hash version (%N)\n"),
10132 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10134 /* Incompatible flag in HTREE root node */
10135 { PR_1_HTREE_INCOMPAT,
10136 N_("@h %i uses an incompatible htree root node flag.\n"),
10137 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10139 /* HTREE too deep */
10140 { PR_1_HTREE_DEPTH,
10141 N_("@h %i has a tree depth (%N) which is too big\n"),
10142 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10144 /* Bad block has indirect block that conflicts with filesystem block */
10145 { PR_1_BB_FS_BLOCK,
10146 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
10148 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10150 /* Resize inode failed */
10151 { PR_1_RESIZE_INODE_CREATE,
10152 N_("Resize @i (re)creation failed: %m."),
10155 /* invalid inode->i_extra_isize */
10156 { PR_1_EXTRA_ISIZE,
10157 N_("@i %i has a extra size (%IS) which is @n\n"),
10158 PROMPT_FIX, PR_PREEN_OK },
10160 /* invalid ea entry->e_name_len */
10161 { PR_1_ATTR_NAME_LEN,
10162 N_("@a in @i %i has a namelen (%N) which is @n\n"),
10163 PROMPT_CLEAR, PR_PREEN_OK },
10165 /* invalid ea entry->e_value_size */
10166 { PR_1_ATTR_VALUE_SIZE,
10167 N_("@a in @i %i has a value size (%N) which is @n\n"),
10168 PROMPT_CLEAR, PR_PREEN_OK },
10170 /* invalid ea entry->e_value_offs */
10171 { PR_1_ATTR_VALUE_OFFSET,
10172 N_("@a in @i %i has a value offset (%N) which is @n\n"),
10173 PROMPT_CLEAR, PR_PREEN_OK },
10175 /* invalid ea entry->e_value_block */
10176 { PR_1_ATTR_VALUE_BLOCK,
10177 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
10178 PROMPT_CLEAR, PR_PREEN_OK },
10180 /* invalid ea entry->e_hash */
10182 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
10183 PROMPT_CLEAR, PR_PREEN_OK },
10185 /* Pass 1b errors */
10187 /* Pass 1B: Rescan for duplicate/bad blocks */
10188 { PR_1B_PASS_HEADER,
10189 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
10190 "Pass 1B: Rescanning for @m @bs\n"),
10193 /* Duplicate/bad block(s) header */
10194 { PR_1B_DUP_BLOCK_HEADER,
10195 N_("@m @b(s) in @i %i:"),
10198 /* Duplicate/bad block(s) in inode */
10201 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
10203 /* Duplicate/bad block(s) end */
10204 { PR_1B_DUP_BLOCK_END,
10206 PROMPT_NONE, PR_PREEN_NOHDR },
10208 /* Error while scanning inodes */
10209 { PR_1B_ISCAN_ERROR,
10210 N_("Error while scanning inodes (%i): %m\n"),
10211 PROMPT_NONE, PR_FATAL },
10213 /* Error allocating inode bitmap */
10214 { PR_1B_ALLOCATE_IBITMAP_ERROR,
10215 N_("@A @i @B (@i_dup_map): %m\n"),
10216 PROMPT_NONE, PR_FATAL },
10218 /* Error while iterating over blocks */
10219 { PR_1B_BLOCK_ITERATE,
10220 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
10223 /* Error adjusting EA refcount */
10224 { PR_1B_ADJ_EA_REFCOUNT,
10225 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
10229 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
10230 { PR_1C_PASS_HEADER,
10231 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
10235 /* Pass 1D: Reconciling multiply-claimed blocks */
10236 { PR_1D_PASS_HEADER,
10237 N_("Pass 1D: Reconciling @m @bs\n"),
10240 /* File has duplicate blocks */
10242 N_("File %Q (@i #%i, mod time %IM) \n"
10243 " has %B @m @b(s), shared with %N file(s):\n"),
10246 /* List of files sharing duplicate blocks */
10247 { PR_1D_DUP_FILE_LIST,
10248 N_("\t%Q (@i #%i, mod time %IM)\n"),
10251 /* File sharing blocks with filesystem metadata */
10252 { PR_1D_SHARE_METADATA,
10253 N_("\t<@f metadata>\n"),
10256 /* Report of how many duplicate/bad inodes */
10257 { PR_1D_NUM_DUP_INODES,
10258 N_("(There are %N @is containing @m @bs.)\n\n"),
10261 /* Duplicated blocks already reassigned or cloned. */
10262 { PR_1D_DUP_BLOCKS_DEALT,
10263 N_("@m @bs already reassigned or cloned.\n\n"),
10266 /* Clone duplicate/bad blocks? */
10267 { PR_1D_CLONE_QUESTION,
10268 "", PROMPT_CLONE, PR_NO_OK },
10271 { PR_1D_DELETE_QUESTION,
10272 "", PROMPT_DELETE, 0 },
10274 /* Couldn't clone file (error) */
10275 { PR_1D_CLONE_ERROR,
10276 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
10278 /* Pass 2 errors */
10280 /* Pass 2: Checking directory structure */
10281 { PR_2_PASS_HEADER,
10282 N_("Pass 2: Checking @d structure\n"),
10285 /* Bad inode number for '.' */
10286 { PR_2_BAD_INODE_DOT,
10287 N_("@n @i number for '.' in @d @i %i.\n"),
10290 /* Directory entry has bad inode number */
10292 N_("@E has @n @i #: %Di.\n"),
10295 /* Directory entry has deleted or unused inode */
10296 { PR_2_UNUSED_INODE,
10297 N_("@E has @D/unused @i %Di. "),
10298 PROMPT_CLEAR, PR_PREEN_OK },
10300 /* Directry entry is link to '.' */
10302 N_("@E @L to '.' "),
10305 /* Directory entry points to inode now located in a bad block */
10307 N_("@E points to @i (%Di) located in a bad @b.\n"),
10310 /* Directory entry contains a link to a directory */
10312 N_("@E @L to @d %P (%Di).\n"),
10315 /* Directory entry contains a link to the root directry */
10317 N_("@E @L to the @r.\n"),
10320 /* Directory entry has illegal characters in its name */
10322 N_("@E has illegal characters in its name.\n"),
10325 /* Missing '.' in directory inode */
10326 { PR_2_MISSING_DOT,
10327 N_("Missing '.' in @d @i %i.\n"),
10330 /* Missing '..' in directory inode */
10331 { PR_2_MISSING_DOT_DOT,
10332 N_("Missing '..' in @d @i %i.\n"),
10335 /* First entry in directory inode doesn't contain '.' */
10336 { PR_2_1ST_NOT_DOT,
10337 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
10340 /* Second entry in directory inode doesn't contain '..' */
10341 { PR_2_2ND_NOT_DOT_DOT,
10342 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
10345 /* i_faddr should be zero */
10347 N_("i_faddr @F %IF, @s zero.\n"),
10350 /* i_file_acl should be zero */
10351 { PR_2_FILE_ACL_ZERO,
10352 N_("i_file_acl @F %If, @s zero.\n"),
10355 /* i_dir_acl should be zero */
10356 { PR_2_DIR_ACL_ZERO,
10357 N_("i_dir_acl @F %Id, @s zero.\n"),
10360 /* i_frag should be zero */
10362 N_("i_frag @F %N, @s zero.\n"),
10365 /* i_fsize should be zero */
10367 N_("i_fsize @F %N, @s zero.\n"),
10370 /* inode has bad mode */
10372 N_("@i %i (%Q) has @n mode (%Im).\n"),
10375 /* directory corrupted */
10376 { PR_2_DIR_CORRUPTED,
10377 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
10378 PROMPT_SALVAGE, 0 },
10380 /* filename too long */
10381 { PR_2_FILENAME_LONG,
10382 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
10383 PROMPT_TRUNCATE, 0 },
10385 /* Directory inode has a missing block (hole) */
10386 { PR_2_DIRECTORY_HOLE,
10387 N_("@d @i %i has an unallocated @b #%B. "),
10388 PROMPT_ALLOCATE, 0 },
10390 /* '.' is not NULL terminated */
10391 { PR_2_DOT_NULL_TERM,
10392 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
10395 /* '..' is not NULL terminated */
10396 { PR_2_DOT_DOT_NULL_TERM,
10397 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
10400 /* Illegal character device inode */
10401 { PR_2_BAD_CHAR_DEV,
10402 N_("@i %i (%Q) is an @I character @v.\n"),
10405 /* Illegal block device inode */
10406 { PR_2_BAD_BLOCK_DEV,
10407 N_("@i %i (%Q) is an @I @b @v.\n"),
10410 /* Duplicate '.' entry */
10412 N_("@E is duplicate '.' @e.\n"),
10415 /* Duplicate '..' entry */
10416 { PR_2_DUP_DOT_DOT,
10417 N_("@E is duplicate '..' @e.\n"),
10420 /* Internal error: couldn't find dir_info */
10422 N_("Internal error: couldn't find dir_info for %i.\n"),
10423 PROMPT_NONE, PR_FATAL },
10425 /* Final rec_len is wrong */
10426 { PR_2_FINAL_RECLEN,
10427 N_("@E has rec_len of %Dr, @s %N.\n"),
10430 /* Error allocating icount structure */
10431 { PR_2_ALLOCATE_ICOUNT,
10432 N_("@A icount structure: %m\n"),
10433 PROMPT_NONE, PR_FATAL },
10435 /* Error iterating over directory blocks */
10436 { PR_2_DBLIST_ITERATE,
10437 N_("Error iterating over @d @bs: %m\n"),
10438 PROMPT_NONE, PR_FATAL },
10440 /* Error reading directory block */
10441 { PR_2_READ_DIRBLOCK,
10442 N_("Error reading @d @b %b (@i %i): %m\n"),
10443 PROMPT_CONTINUE, 0 },
10445 /* Error writing directory block */
10446 { PR_2_WRITE_DIRBLOCK,
10447 N_("Error writing @d @b %b (@i %i): %m\n"),
10448 PROMPT_CONTINUE, 0 },
10450 /* Error allocating new directory block */
10451 { PR_2_ALLOC_DIRBOCK,
10452 N_("@A new @d @b for @i %i (%s): %m\n"),
10455 /* Error deallocating inode */
10456 { PR_2_DEALLOC_INODE,
10457 N_("Error deallocating @i %i: %m\n"),
10458 PROMPT_NONE, PR_FATAL },
10460 /* Directory entry for '.' is big. Split? */
10462 N_("@d @e for '.' is big. "),
10463 PROMPT_SPLIT, PR_NO_OK },
10465 /* Illegal FIFO inode */
10467 N_("@i %i (%Q) is an @I FIFO.\n"),
10470 /* Illegal socket inode */
10472 N_("@i %i (%Q) is an @I socket.\n"),
10475 /* Directory filetype not set */
10476 { PR_2_SET_FILETYPE,
10477 N_("Setting filetype for @E to %N.\n"),
10478 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
10480 /* Directory filetype incorrect */
10481 { PR_2_BAD_FILETYPE,
10482 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
10485 /* Directory filetype set on filesystem */
10486 { PR_2_CLEAR_FILETYPE,
10487 N_("@E has filetype set.\n"),
10488 PROMPT_CLEAR, PR_PREEN_OK },
10490 /* Directory filename is null */
10492 N_("@E has a @z name.\n"),
10495 /* Invalid symlink */
10496 { PR_2_INVALID_SYMLINK,
10497 N_("Symlink %Q (@i #%i) is @n.\n"),
10500 /* i_file_acl (extended attribute block) is bad */
10501 { PR_2_FILE_ACL_BAD,
10502 N_("@a @b @F @n (%If).\n"),
10505 /* Filesystem contains large files, but has no such flag in sb */
10506 { PR_2_FEATURE_LARGE_FILES,
10507 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
10510 /* Node in HTREE directory not referenced */
10511 { PR_2_HTREE_NOTREF,
10512 N_("@p @h %d: node (%B) not referenced\n"),
10515 /* Node in HTREE directory referenced twice */
10516 { PR_2_HTREE_DUPREF,
10517 N_("@p @h %d: node (%B) referenced twice\n"),
10520 /* Node in HTREE directory has bad min hash */
10521 { PR_2_HTREE_MIN_HASH,
10522 N_("@p @h %d: node (%B) has bad min hash\n"),
10525 /* Node in HTREE directory has bad max hash */
10526 { PR_2_HTREE_MAX_HASH,
10527 N_("@p @h %d: node (%B) has bad max hash\n"),
10530 /* Clear invalid HTREE directory */
10531 { PR_2_HTREE_CLEAR,
10532 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
10534 /* Bad block in htree interior node */
10535 { PR_2_HTREE_BADBLK,
10536 N_("@p @h %d (%q): bad @b number %b.\n"),
10537 PROMPT_CLEAR_HTREE, 0 },
10539 /* Error adjusting EA refcount */
10540 { PR_2_ADJ_EA_REFCOUNT,
10541 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
10542 PROMPT_NONE, PR_FATAL },
10544 /* Invalid HTREE root node */
10545 { PR_2_HTREE_BAD_ROOT,
10546 N_("@p @h %d: root node is @n\n"),
10547 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10549 /* Invalid HTREE limit */
10550 { PR_2_HTREE_BAD_LIMIT,
10551 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
10552 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10554 /* Invalid HTREE count */
10555 { PR_2_HTREE_BAD_COUNT,
10556 N_("@p @h %d: node (%B) has @n count (%N)\n"),
10557 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10559 /* HTREE interior node has out-of-order hashes in table */
10560 { PR_2_HTREE_HASH_ORDER,
10561 N_("@p @h %d: node (%B) has an unordered hash table\n"),
10562 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10564 /* Node in HTREE directory has invalid depth */
10565 { PR_2_HTREE_BAD_DEPTH,
10566 N_("@p @h %d: node (%B) has @n depth\n"),
10569 /* Duplicate directory entry found */
10570 { PR_2_DUPLICATE_DIRENT,
10571 N_("Duplicate @E found. "),
10574 /* Non-unique filename found */
10575 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
10576 N_("@E has a non-unique filename.\nRename to %s"),
10579 /* Duplicate directory entry found */
10580 { PR_2_REPORT_DUP_DIRENT,
10581 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
10584 /* Pass 3 errors */
10586 /* Pass 3: Checking directory connectivity */
10587 { PR_3_PASS_HEADER,
10588 N_("Pass 3: Checking @d connectivity\n"),
10591 /* Root inode not allocated */
10592 { PR_3_NO_ROOT_INODE,
10593 N_("@r not allocated. "),
10594 PROMPT_ALLOCATE, 0 },
10596 /* No room in lost+found */
10597 { PR_3_EXPAND_LF_DIR,
10598 N_("No room in @l @d. "),
10599 PROMPT_EXPAND, 0 },
10601 /* Unconnected directory inode */
10602 { PR_3_UNCONNECTED_DIR,
10603 N_("Unconnected @d @i %i (%p)\n"),
10604 PROMPT_CONNECT, 0 },
10606 /* /lost+found not found */
10608 N_("/@l not found. "),
10609 PROMPT_CREATE, PR_PREEN_OK },
10611 /* .. entry is incorrect */
10612 { PR_3_BAD_DOT_DOT,
10613 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
10616 /* Bad or non-existent /lost+found. Cannot reconnect */
10618 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
10621 /* Could not expand /lost+found */
10622 { PR_3_CANT_EXPAND_LPF,
10623 N_("Could not expand /@l: %m\n"),
10626 /* Could not reconnect inode */
10627 { PR_3_CANT_RECONNECT,
10628 N_("Could not reconnect %i: %m\n"),
10631 /* Error while trying to find /lost+found */
10632 { PR_3_ERR_FIND_LPF,
10633 N_("Error while trying to find /@l: %m\n"),
10636 /* Error in ext2fs_new_block while creating /lost+found */
10637 { PR_3_ERR_LPF_NEW_BLOCK,
10638 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
10641 /* Error in ext2fs_new_inode while creating /lost+found */
10642 { PR_3_ERR_LPF_NEW_INODE,
10643 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
10646 /* Error in ext2fs_new_dir_block while creating /lost+found */
10647 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
10648 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
10651 /* Error while writing directory block for /lost+found */
10652 { PR_3_ERR_LPF_WRITE_BLOCK,
10653 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
10656 /* Error while adjusting inode count */
10657 { PR_3_ADJUST_INODE,
10658 N_("Error while adjusting @i count on @i %i\n"),
10661 /* Couldn't fix parent directory -- error */
10662 { PR_3_FIX_PARENT_ERR,
10663 N_("Couldn't fix parent of @i %i: %m\n\n"),
10666 /* Couldn't fix parent directory -- couldn't find it */
10667 { PR_3_FIX_PARENT_NOFIND,
10668 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
10671 /* Error allocating inode bitmap */
10672 { PR_3_ALLOCATE_IBITMAP_ERROR,
10673 N_("@A @i @B (%N): %m\n"),
10674 PROMPT_NONE, PR_FATAL },
10676 /* Error creating root directory */
10677 { PR_3_CREATE_ROOT_ERROR,
10678 N_("Error creating root @d (%s): %m\n"),
10679 PROMPT_NONE, PR_FATAL },
10681 /* Error creating lost and found directory */
10682 { PR_3_CREATE_LPF_ERROR,
10683 N_("Error creating /@l @d (%s): %m\n"),
10684 PROMPT_NONE, PR_FATAL },
10686 /* Root inode is not directory; aborting */
10687 { PR_3_ROOT_NOT_DIR_ABORT,
10688 N_("@r is not a @d; aborting.\n"),
10689 PROMPT_NONE, PR_FATAL },
10691 /* Cannot proceed without a root inode. */
10692 { PR_3_NO_ROOT_INODE_ABORT,
10693 N_("Cannot proceed without a @r.\n"),
10694 PROMPT_NONE, PR_FATAL },
10696 /* Internal error: couldn't find dir_info */
10698 N_("Internal error: couldn't find dir_info for %i.\n"),
10699 PROMPT_NONE, PR_FATAL },
10701 /* Lost+found not a directory */
10703 N_("/@l is not a @d (ino=%i)\n"),
10704 PROMPT_UNLINK, 0 },
10706 /* Pass 3A Directory Optimization */
10708 /* Pass 3A: Optimizing directories */
10709 { PR_3A_PASS_HEADER,
10710 N_("Pass 3A: Optimizing directories\n"),
10711 PROMPT_NONE, PR_PREEN_NOMSG },
10713 /* Error iterating over directories */
10714 { PR_3A_OPTIMIZE_ITER,
10715 N_("Failed to create dirs_to_hash iterator: %m"),
10718 /* Error rehash directory */
10719 { PR_3A_OPTIMIZE_DIR_ERR,
10720 N_("Failed to optimize directory %q (%d): %m"),
10723 /* Rehashing dir header */
10724 { PR_3A_OPTIMIZE_DIR_HEADER,
10725 N_("Optimizing directories: "),
10726 PROMPT_NONE, PR_MSG_ONLY },
10728 /* Rehashing directory %d */
10729 { PR_3A_OPTIMIZE_DIR,
10731 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
10733 /* Rehashing dir end */
10734 { PR_3A_OPTIMIZE_DIR_END,
10736 PROMPT_NONE, PR_PREEN_NOHDR },
10738 /* Pass 4 errors */
10740 /* Pass 4: Checking reference counts */
10741 { PR_4_PASS_HEADER,
10742 N_("Pass 4: Checking reference counts\n"),
10745 /* Unattached zero-length inode */
10746 { PR_4_ZERO_LEN_INODE,
10747 N_("@u @z @i %i. "),
10748 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
10750 /* Unattached inode */
10751 { PR_4_UNATTACHED_INODE,
10753 PROMPT_CONNECT, 0 },
10755 /* Inode ref count wrong */
10756 { PR_4_BAD_REF_COUNT,
10757 N_("@i %i ref count is %Il, @s %N. "),
10758 PROMPT_FIX, PR_PREEN_OK },
10760 { PR_4_INCONSISTENT_COUNT,
10761 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
10762 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
10763 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
10764 "They @s the same!\n"),
10767 /* Pass 5 errors */
10769 /* Pass 5: Checking group summary information */
10770 { PR_5_PASS_HEADER,
10771 N_("Pass 5: Checking @g summary information\n"),
10774 /* Padding at end of inode bitmap is not set. */
10775 { PR_5_INODE_BMAP_PADDING,
10776 N_("Padding at end of @i @B is not set. "),
10777 PROMPT_FIX, PR_PREEN_OK },
10779 /* Padding at end of block bitmap is not set. */
10780 { PR_5_BLOCK_BMAP_PADDING,
10781 N_("Padding at end of @b @B is not set. "),
10782 PROMPT_FIX, PR_PREEN_OK },
10784 /* Block bitmap differences header */
10785 { PR_5_BLOCK_BITMAP_HEADER,
10786 N_("@b @B differences: "),
10787 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
10789 /* Block not used, but marked in bitmap */
10790 { PR_5_BLOCK_UNUSED,
10792 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10794 /* Block used, but not marked used in bitmap */
10797 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10799 /* Block bitmap differences end */
10800 { PR_5_BLOCK_BITMAP_END,
10802 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10804 /* Inode bitmap differences header */
10805 { PR_5_INODE_BITMAP_HEADER,
10806 N_("@i @B differences: "),
10807 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10809 /* Inode not used, but marked in bitmap */
10810 { PR_5_INODE_UNUSED,
10812 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10814 /* Inode used, but not marked used in bitmap */
10817 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10819 /* Inode bitmap differences end */
10820 { PR_5_INODE_BITMAP_END,
10822 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10824 /* Free inodes count for group wrong */
10825 { PR_5_FREE_INODE_COUNT_GROUP,
10826 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
10827 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10829 /* Directories count for group wrong */
10830 { PR_5_FREE_DIR_COUNT_GROUP,
10831 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
10832 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10834 /* Free inodes count wrong */
10835 { PR_5_FREE_INODE_COUNT,
10836 N_("Free @is count wrong (%i, counted=%j).\n"),
10837 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10839 /* Free blocks count for group wrong */
10840 { PR_5_FREE_BLOCK_COUNT_GROUP,
10841 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
10842 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10844 /* Free blocks count wrong */
10845 { PR_5_FREE_BLOCK_COUNT,
10846 N_("Free @bs count wrong (%b, counted=%c).\n"),
10847 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
10849 /* Programming error: bitmap endpoints don't match */
10850 { PR_5_BMAP_ENDPOINTS,
10851 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
10852 "match calculated @B endpoints (%i, %j)\n"),
10853 PROMPT_NONE, PR_FATAL },
10855 /* Internal error: fudging end of bitmap */
10856 { PR_5_FUDGE_BITMAP_ERROR,
10857 N_("Internal error: fudging end of bitmap (%N)\n"),
10858 PROMPT_NONE, PR_FATAL },
10860 /* Error copying in replacement inode bitmap */
10861 { PR_5_COPY_IBITMAP_ERROR,
10862 N_("Error copying in replacement @i @B: %m\n"),
10863 PROMPT_NONE, PR_FATAL },
10865 /* Error copying in replacement block bitmap */
10866 { PR_5_COPY_BBITMAP_ERROR,
10867 N_("Error copying in replacement @b @B: %m\n"),
10868 PROMPT_NONE, PR_FATAL },
10870 /* Block range not used, but marked in bitmap */
10871 { PR_5_BLOCK_RANGE_UNUSED,
10873 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10875 /* Block range used, but not marked used in bitmap */
10876 { PR_5_BLOCK_RANGE_USED,
10878 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10880 /* Inode range not used, but marked in bitmap */
10881 { PR_5_INODE_RANGE_UNUSED,
10883 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10885 /* Inode range used, but not marked used in bitmap */
10886 { PR_5_INODE_RANGE_USED,
10888 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10894 * This is the latch flags register. It allows several problems to be
10895 * "latched" together. This means that the user has to answer but one
10896 * question for the set of problems, and all of the associated
10897 * problems will be either fixed or not fixed.
10899 static struct latch_descr pr_latch_info[] = {
10900 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
10901 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
10902 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
10903 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
10904 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
10905 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
10906 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
10907 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
10908 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
10912 static const struct e2fsck_problem *find_problem(problem_t code)
10916 for (i=0; problem_table[i].e2p_code; i++) {
10917 if (problem_table[i].e2p_code == code)
10918 return &problem_table[i];
10923 static struct latch_descr *find_latch(int code)
10927 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
10928 if (pr_latch_info[i].latch_code == code)
10929 return &pr_latch_info[i];
10934 int end_problem_latch(e2fsck_t ctx, int mask)
10936 struct latch_descr *ldesc;
10937 struct problem_context pctx;
10940 ldesc = find_latch(mask);
10941 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
10942 clear_problem_context(&pctx);
10943 answer = fix_problem(ctx, ldesc->end_message, &pctx);
10945 ldesc->flags &= ~(PRL_VARIABLE);
10949 int set_latch_flags(int mask, int setflags, int clearflags)
10951 struct latch_descr *ldesc;
10953 ldesc = find_latch(mask);
10956 ldesc->flags |= setflags;
10957 ldesc->flags &= ~clearflags;
10961 void clear_problem_context(struct problem_context *ctx)
10963 memset(ctx, 0, sizeof(struct problem_context));
10964 ctx->blkcount = -1;
10968 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
10970 ext2_filsys fs = ctx->fs;
10971 const struct e2fsck_problem *ptr;
10972 struct latch_descr *ldesc = 0;
10973 const char *message;
10974 int def_yn, answer, ans;
10975 int print_answer = 0;
10978 ptr = find_problem(code);
10980 printf(_("Unhandled error code (0x%x)!\n"), code);
10984 if ((ptr->flags & PR_NO_DEFAULT) ||
10985 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
10986 (ctx->options & E2F_OPT_NO))
10990 * Do special latch processing. This is where we ask the
10991 * latch question, if it exists
10993 if (ptr->flags & PR_LATCH_MASK) {
10994 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
10995 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
10996 ans = fix_problem(ctx, ldesc->question, pctx);
10998 ldesc->flags |= PRL_YES;
11000 ldesc->flags |= PRL_NO;
11001 ldesc->flags |= PRL_LATCHED;
11003 if (ldesc->flags & PRL_SUPPRESS)
11006 if ((ptr->flags & PR_PREEN_NOMSG) &&
11007 (ctx->options & E2F_OPT_PREEN))
11009 if ((ptr->flags & PR_NO_NOMSG) &&
11010 (ctx->options & E2F_OPT_NO))
11013 message = ptr->e2p_description;
11014 if ((ctx->options & E2F_OPT_PREEN) &&
11015 !(ptr->flags & PR_PREEN_NOHDR)) {
11016 printf("%s: ", ctx->device_name ?
11017 ctx->device_name : ctx->filesystem_name);
11020 print_e2fsck_message(ctx, _(message), pctx, 1);
11022 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
11025 if (ptr->flags & PR_FATAL)
11026 fatal_error(ctx, 0);
11028 if (ptr->prompt == PROMPT_NONE) {
11029 if (ptr->flags & PR_NOCOLLATE)
11034 if (ctx->options & E2F_OPT_PREEN) {
11036 if (!(ptr->flags & PR_PREEN_NOMSG))
11038 } else if ((ptr->flags & PR_LATCH_MASK) &&
11039 (ldesc->flags & (PRL_YES | PRL_NO))) {
11042 if (ldesc->flags & PRL_YES)
11047 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
11048 if (!answer && !(ptr->flags & PR_NO_OK))
11049 ext2fs_unmark_valid(fs);
11052 printf("%s.\n", answer ?
11053 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
11057 if ((ptr->prompt == PROMPT_ABORT) && answer)
11058 fatal_error(ctx, 0);
11060 if (ptr->flags & PR_AFTER_CODE)
11061 answer = fix_problem(ctx, ptr->second_code, pctx);
11067 * linux/fs/recovery.c
11069 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
11073 * Maintain information about the progress of the recovery job, so that
11074 * the different passes can carry information between them.
11076 struct recovery_info
11078 tid_t start_transaction;
11079 tid_t end_transaction;
11083 int nr_revoke_hits;
11086 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
11087 static int do_one_pass(journal_t *journal,
11088 struct recovery_info *info, enum passtype pass);
11089 static int scan_revoke_records(journal_t *, struct buffer_head *,
11090 tid_t, struct recovery_info *);
11093 * Read a block from the journal
11096 static int jread(struct buffer_head **bhp, journal_t *journal,
11097 unsigned int offset)
11100 unsigned long blocknr;
11101 struct buffer_head *bh;
11105 err = journal_bmap(journal, offset, &blocknr);
11108 printf ("JBD: bad block at offset %u\n", offset);
11112 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
11116 if (!buffer_uptodate(bh)) {
11117 /* If this is a brand new buffer, start readahead.
11118 Otherwise, we assume we are already reading it. */
11119 if (!buffer_req(bh))
11120 do_readahead(journal, offset);
11121 wait_on_buffer(bh);
11124 if (!buffer_uptodate(bh)) {
11125 printf ("JBD: Failed to read block at offset %u\n", offset);
11136 * Count the number of in-use tags in a journal descriptor block.
11139 static int count_tags(struct buffer_head *bh, int size)
11142 journal_block_tag_t * tag;
11145 tagp = &bh->b_data[sizeof(journal_header_t)];
11147 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
11148 tag = (journal_block_tag_t *) tagp;
11151 tagp += sizeof(journal_block_tag_t);
11152 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
11155 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
11163 /* Make sure we wrap around the log correctly! */
11164 #define wrap(journal, var) \
11166 if (var >= (journal)->j_last) \
11167 var -= ((journal)->j_last - (journal)->j_first); \
11171 * int journal_recover(journal_t *journal) - recovers a on-disk journal
11172 * @journal: the journal to recover
11174 * The primary function for recovering the log contents when mounting a
11175 * journaled device.
11177 * Recovery is done in three passes. In the first pass, we look for the
11178 * end of the log. In the second, we assemble the list of revoke
11179 * blocks. In the third and final pass, we replay any un-revoked blocks
11182 int journal_recover(journal_t *journal)
11185 journal_superblock_t * sb;
11187 struct recovery_info info;
11189 memset(&info, 0, sizeof(info));
11190 sb = journal->j_superblock;
11193 * The journal superblock's s_start field (the current log head)
11194 * is always zero if, and only if, the journal was cleanly
11198 if (!sb->s_start) {
11199 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
11203 err = do_one_pass(journal, &info, PASS_SCAN);
11205 err = do_one_pass(journal, &info, PASS_REVOKE);
11207 err = do_one_pass(journal, &info, PASS_REPLAY);
11209 /* Restart the log at the next transaction ID, thus invalidating
11210 * any existing commit records in the log. */
11211 journal->j_transaction_sequence = ++info.end_transaction;
11213 journal_clear_revoke(journal);
11214 sync_blockdev(journal->j_fs_dev);
11218 static int do_one_pass(journal_t *journal,
11219 struct recovery_info *info, enum passtype pass)
11221 unsigned int first_commit_ID, next_commit_ID;
11222 unsigned long next_log_block;
11223 int err, success = 0;
11224 journal_superblock_t * sb;
11225 journal_header_t * tmp;
11226 struct buffer_head * bh;
11227 unsigned int sequence;
11230 /* Precompute the maximum metadata descriptors in a descriptor block */
11231 int MAX_BLOCKS_PER_DESC;
11232 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
11233 / sizeof(journal_block_tag_t));
11236 * First thing is to establish what we expect to find in the log
11237 * (in terms of transaction IDs), and where (in terms of log
11238 * block offsets): query the superblock.
11241 sb = journal->j_superblock;
11242 next_commit_ID = ntohl(sb->s_sequence);
11243 next_log_block = ntohl(sb->s_start);
11245 first_commit_ID = next_commit_ID;
11246 if (pass == PASS_SCAN)
11247 info->start_transaction = first_commit_ID;
11250 * Now we walk through the log, transaction by transaction,
11251 * making sure that each transaction has a commit block in the
11252 * expected place. Each complete transaction gets replayed back
11253 * into the main filesystem.
11259 journal_block_tag_t * tag;
11260 struct buffer_head * obh;
11261 struct buffer_head * nbh;
11263 /* If we already know where to stop the log traversal,
11264 * check right now that we haven't gone past the end of
11267 if (pass != PASS_SCAN)
11268 if (tid_geq(next_commit_ID, info->end_transaction))
11271 /* Skip over each chunk of the transaction looking
11272 * either the next descriptor block or the final commit
11275 err = jread(&bh, journal, next_log_block);
11280 wrap(journal, next_log_block);
11282 /* What kind of buffer is it?
11284 * If it is a descriptor block, check that it has the
11285 * expected sequence number. Otherwise, we're all done
11288 tmp = (journal_header_t *)bh->b_data;
11290 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
11295 blocktype = ntohl(tmp->h_blocktype);
11296 sequence = ntohl(tmp->h_sequence);
11298 if (sequence != next_commit_ID) {
11303 /* OK, we have a valid descriptor block which matches
11304 * all of the sequence number checks. What are we going
11305 * to do with it? That depends on the pass... */
11307 switch(blocktype) {
11308 case JFS_DESCRIPTOR_BLOCK:
11309 /* If it is a valid descriptor block, replay it
11310 * in pass REPLAY; otherwise, just skip over the
11311 * blocks it describes. */
11312 if (pass != PASS_REPLAY) {
11314 count_tags(bh, journal->j_blocksize);
11315 wrap(journal, next_log_block);
11320 /* A descriptor block: we can now write all of
11321 * the data blocks. Yay, useful work is finally
11322 * getting done here! */
11324 tagp = &bh->b_data[sizeof(journal_header_t)];
11325 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
11326 <= journal->j_blocksize) {
11327 unsigned long io_block;
11329 tag = (journal_block_tag_t *) tagp;
11330 flags = ntohl(tag->t_flags);
11332 io_block = next_log_block++;
11333 wrap(journal, next_log_block);
11334 err = jread(&obh, journal, io_block);
11336 /* Recover what we can, but
11337 * report failure at the end. */
11339 printf ("JBD: IO error %d recovering "
11340 "block %ld in log\n",
11343 unsigned long blocknr;
11345 blocknr = ntohl(tag->t_blocknr);
11347 /* If the block has been
11348 * revoked, then we're all done
11350 if (journal_test_revoke
11354 ++info->nr_revoke_hits;
11358 /* Find a buffer for the new
11359 * data being restored */
11360 nbh = getblk(journal->j_fs_dev,
11362 journal->j_blocksize);
11364 printf ("JBD: Out of memory "
11365 "during recovery.\n");
11373 memcpy(nbh->b_data, obh->b_data,
11374 journal->j_blocksize);
11375 if (flags & JFS_FLAG_ESCAPE) {
11376 *((unsigned int *)bh->b_data) =
11377 htonl(JFS_MAGIC_NUMBER);
11380 mark_buffer_uptodate(nbh, 1);
11381 mark_buffer_dirty(nbh);
11382 ++info->nr_replays;
11383 /* ll_rw_block(WRITE, 1, &nbh); */
11384 unlock_buffer(nbh);
11390 tagp += sizeof(journal_block_tag_t);
11391 if (!(flags & JFS_FLAG_SAME_UUID))
11394 if (flags & JFS_FLAG_LAST_TAG)
11401 case JFS_COMMIT_BLOCK:
11402 /* Found an expected commit block: not much to
11403 * do other than move on to the next sequence
11409 case JFS_REVOKE_BLOCK:
11410 /* If we aren't in the REVOKE pass, then we can
11411 * just skip over this block. */
11412 if (pass != PASS_REVOKE) {
11417 err = scan_revoke_records(journal, bh,
11418 next_commit_ID, info);
11431 * We broke out of the log scan loop: either we came to the
11432 * known end of the log or we found an unexpected block in the
11433 * log. If the latter happened, then we know that the "current"
11434 * transaction marks the end of the valid log.
11437 if (pass == PASS_SCAN)
11438 info->end_transaction = next_commit_ID;
11440 /* It's really bad news if different passes end up at
11441 * different places (but possible due to IO errors). */
11442 if (info->end_transaction != next_commit_ID) {
11443 printf ("JBD: recovery pass %d ended at "
11444 "transaction %u, expected %u\n",
11445 pass, next_commit_ID, info->end_transaction);
11458 /* Scan a revoke record, marking all blocks mentioned as revoked. */
11460 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
11461 tid_t sequence, struct recovery_info *info)
11463 journal_revoke_header_t *header;
11466 header = (journal_revoke_header_t *) bh->b_data;
11467 offset = sizeof(journal_revoke_header_t);
11468 max = ntohl(header->r_count);
11470 while (offset < max) {
11471 unsigned long blocknr;
11474 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
11476 err = journal_set_revoke(journal, blocknr, sequence);
11479 ++info->nr_revokes;
11486 * rehash.c --- rebuild hash tree directories
11488 * This algorithm is designed for simplicity of implementation and to
11489 * pack the directory as much as possible. It however requires twice
11490 * as much memory as the size of the directory. The maximum size
11491 * directory supported using a 4k blocksize is roughly a gigabyte, and
11492 * so there may very well be problems with machines that don't have
11493 * virtual memory, and obscenely large directories.
11495 * An alternate algorithm which is much more disk intensive could be
11496 * written, and probably will need to be written in the future. The
11497 * design goals of such an algorithm are: (a) use (roughly) constant
11498 * amounts of memory, no matter how large the directory, (b) the
11499 * directory must be safe at all times, even if e2fsck is interrupted
11500 * in the middle, (c) we must use minimal amounts of extra disk
11501 * blocks. This pretty much requires an incremental approach, where
11502 * we are reading from one part of the directory, and inserting into
11503 * the front half. So the algorithm will have to keep track of a
11504 * moving block boundary between the new tree and the old tree, and
11505 * files will need to be moved from the old directory and inserted
11506 * into the new tree. If the new directory requires space which isn't
11507 * yet available, blocks from the beginning part of the old directory
11508 * may need to be moved to the end of the directory to make room for
11511 * --------------------------------------------------------
11512 * | new tree | | old tree |
11513 * --------------------------------------------------------
11515 * tail new head old
11517 * This is going to be a pain in the tuckus to implement, and will
11518 * require a lot more disk accesses. So I'm going to skip it for now;
11519 * it's only really going to be an issue for really, really big
11520 * filesystems (when we reach the level of tens of millions of files
11521 * in a single directory). It will probably be easier to simply
11522 * require that e2fsck use VM first.
11525 struct fill_dir_struct {
11527 struct ext2_inode *inode;
11530 struct hash_entry *harray;
11531 int max_array, num_array;
11537 struct hash_entry {
11538 ext2_dirhash_t hash;
11539 ext2_dirhash_t minor_hash;
11540 struct ext2_dir_entry *dir;
11547 ext2_dirhash_t *hashes;
11550 static int fill_dir_block(ext2_filsys fs,
11552 e2_blkcnt_t blockcnt,
11553 blk_t ref_block FSCK_ATTR((unused)),
11554 int ref_offset FSCK_ATTR((unused)),
11557 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
11558 struct hash_entry *new_array, *ent;
11559 struct ext2_dir_entry *dirent;
11561 unsigned int offset, dir_offset;
11566 offset = blockcnt * fs->blocksize;
11567 if (offset + fs->blocksize > fd->inode->i_size) {
11568 fd->err = EXT2_ET_DIR_CORRUPTED;
11569 return BLOCK_ABORT;
11571 dir = (fd->buf+offset);
11572 if (HOLE_BLKADDR(*block_nr)) {
11573 memset(dir, 0, fs->blocksize);
11574 dirent = (struct ext2_dir_entry *) dir;
11575 dirent->rec_len = fs->blocksize;
11577 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
11579 return BLOCK_ABORT;
11581 /* While the directory block is "hot", index it. */
11583 while (dir_offset < fs->blocksize) {
11584 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
11585 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
11586 (dirent->rec_len < 8) ||
11587 ((dirent->rec_len % 4) != 0) ||
11588 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
11589 fd->err = EXT2_ET_DIR_CORRUPTED;
11590 return BLOCK_ABORT;
11592 dir_offset += dirent->rec_len;
11593 if (dirent->inode == 0)
11595 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
11596 (dirent->name[0] == '.'))
11598 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
11599 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
11600 fd->parent = dirent->inode;
11603 if (fd->num_array >= fd->max_array) {
11604 new_array = realloc(fd->harray,
11605 sizeof(struct hash_entry) * (fd->max_array+500));
11608 return BLOCK_ABORT;
11610 fd->harray = new_array;
11611 fd->max_array += 500;
11613 ent = fd->harray + fd->num_array++;
11615 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
11617 ent->hash = ent->minor_hash = 0;
11619 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
11621 dirent->name_len & 0xFF,
11622 fs->super->s_hash_seed,
11623 &ent->hash, &ent->minor_hash);
11625 return BLOCK_ABORT;
11632 /* Used for sorting the hash entry */
11633 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
11635 const struct hash_entry *he_a = (const struct hash_entry *) a;
11636 const struct hash_entry *he_b = (const struct hash_entry *) b;
11640 min_len = he_a->dir->name_len;
11641 if (min_len > he_b->dir->name_len)
11642 min_len = he_b->dir->name_len;
11644 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
11646 if (he_a->dir->name_len > he_b->dir->name_len)
11648 else if (he_a->dir->name_len < he_b->dir->name_len)
11651 ret = he_b->dir->inode - he_a->dir->inode;
11656 /* Used for sorting the hash entry */
11657 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
11659 const struct hash_entry *he_a = (const struct hash_entry *) a;
11660 const struct hash_entry *he_b = (const struct hash_entry *) b;
11663 if (he_a->hash > he_b->hash)
11665 else if (he_a->hash < he_b->hash)
11668 if (he_a->minor_hash > he_b->minor_hash)
11670 else if (he_a->minor_hash < he_b->minor_hash)
11673 ret = name_cmp(a, b);
11678 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
11684 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
11687 outdir->buf = new_mem;
11688 new_mem = realloc(outdir->hashes,
11689 blocks * sizeof(ext2_dirhash_t));
11692 outdir->hashes = new_mem;
11694 outdir->buf = malloc(blocks * fs->blocksize);
11695 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
11698 outdir->max = blocks;
11702 static void free_out_dir(struct out_dir *outdir)
11705 free(outdir->hashes);
11710 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
11715 if (outdir->num >= outdir->max) {
11716 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
11720 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
11721 memset(*ret, 0, fs->blocksize);
11726 * This function is used to make a unique filename. We do this by
11727 * appending ~0, and then incrementing the number. However, we cannot
11728 * expand the length of the filename beyond the padding available in
11729 * the directory entry.
11731 static void mutate_name(char *str, __u16 *len)
11734 __u16 l = *len & 0xFF, h = *len & 0xff00;
11737 * First check to see if it looks the name has been mutated
11740 for (i = l-1; i > 0; i--) {
11741 if (!isdigit(str[i]))
11744 if ((i == l-1) || (str[i] != '~')) {
11745 if (((l-1) & 3) < 2)
11754 for (i = l-1; i >= 0; i--) {
11755 if (isdigit(str[i])) {
11767 else if (str[0] == 'Z') {
11772 } else if (i > 0) {
11785 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
11787 struct fill_dir_struct *fd)
11789 struct problem_context pctx;
11790 struct hash_entry *ent, *prev;
11793 char new_name[256];
11796 clear_problem_context(&pctx);
11799 for (i=1; i < fd->num_array; i++) {
11800 ent = fd->harray + i;
11802 if (!ent->dir->inode ||
11803 ((ent->dir->name_len & 0xFF) !=
11804 (prev->dir->name_len & 0xFF)) ||
11805 (strncmp(ent->dir->name, prev->dir->name,
11806 ent->dir->name_len & 0xFF)))
11808 pctx.dirent = ent->dir;
11809 if ((ent->dir->inode == prev->dir->inode) &&
11810 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
11811 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
11812 ent->dir->inode = 0;
11816 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
11817 new_len = ent->dir->name_len;
11818 mutate_name(new_name, &new_len);
11819 for (j=0; j < fd->num_array; j++) {
11821 ((ent->dir->name_len & 0xFF) !=
11822 (fd->harray[j].dir->name_len & 0xFF)) ||
11823 (strncmp(new_name, fd->harray[j].dir->name,
11826 mutate_name(new_name, &new_len);
11830 new_name[new_len & 0xFF] = 0;
11831 pctx.str = new_name;
11832 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
11833 memcpy(ent->dir->name, new_name, new_len & 0xFF);
11834 ent->dir->name_len = new_len;
11835 ext2fs_dirhash(fs->super->s_def_hash_version,
11837 ent->dir->name_len & 0xFF,
11838 fs->super->s_hash_seed,
11839 &ent->hash, &ent->minor_hash);
11847 static errcode_t copy_dir_entries(ext2_filsys fs,
11848 struct fill_dir_struct *fd,
11849 struct out_dir *outdir)
11853 struct hash_entry *ent;
11854 struct ext2_dir_entry *dirent;
11855 int i, rec_len, left;
11856 ext2_dirhash_t prev_hash;
11860 retval = alloc_size_dir(fs, outdir,
11861 (fd->dir_size / fs->blocksize) + 2);
11864 outdir->num = fd->compress ? 0 : 1;
11866 outdir->hashes[0] = 0;
11868 if ((retval = get_next_block(fs, outdir, &block_start)))
11870 dirent = (struct ext2_dir_entry *) block_start;
11871 left = fs->blocksize;
11872 for (i=0; i < fd->num_array; i++) {
11873 ent = fd->harray + i;
11874 if (ent->dir->inode == 0)
11876 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
11877 if (rec_len > left) {
11879 dirent->rec_len += left;
11880 if ((retval = get_next_block(fs, outdir,
11885 left = fs->blocksize - offset;
11886 dirent = (struct ext2_dir_entry *) (block_start + offset);
11888 if (ent->hash == prev_hash)
11889 outdir->hashes[outdir->num-1] = ent->hash | 1;
11891 outdir->hashes[outdir->num-1] = ent->hash;
11893 dirent->inode = ent->dir->inode;
11894 dirent->name_len = ent->dir->name_len;
11895 dirent->rec_len = rec_len;
11896 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
11900 dirent->rec_len += left;
11904 prev_hash = ent->hash;
11907 dirent->rec_len += left;
11913 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
11914 ext2_ino_t ino, ext2_ino_t parent)
11916 struct ext2_dir_entry *dir;
11917 struct ext2_dx_root_info *root;
11918 struct ext2_dx_countlimit *limits;
11921 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
11922 filetype = EXT2_FT_DIR << 8;
11924 memset(buf, 0, fs->blocksize);
11925 dir = (struct ext2_dir_entry *) buf;
11927 dir->name[0] = '.';
11928 dir->name_len = 1 | filetype;
11930 dir = (struct ext2_dir_entry *) (buf + 12);
11931 dir->inode = parent;
11932 dir->name[0] = '.';
11933 dir->name[1] = '.';
11934 dir->name_len = 2 | filetype;
11935 dir->rec_len = fs->blocksize - 12;
11937 root = (struct ext2_dx_root_info *) (buf+24);
11938 root->reserved_zero = 0;
11939 root->hash_version = fs->super->s_def_hash_version;
11940 root->info_length = 8;
11941 root->indirect_levels = 0;
11942 root->unused_flags = 0;
11944 limits = (struct ext2_dx_countlimit *) (buf+32);
11945 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
11952 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
11954 struct ext2_dir_entry *dir;
11955 struct ext2_dx_countlimit *limits;
11957 memset(buf, 0, fs->blocksize);
11958 dir = (struct ext2_dir_entry *) buf;
11960 dir->rec_len = fs->blocksize;
11962 limits = (struct ext2_dx_countlimit *) (buf+8);
11963 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
11966 return (struct ext2_dx_entry *) limits;
11970 * This function takes the leaf nodes which have been written in
11971 * outdir, and populates the root node and any necessary interior nodes.
11973 static errcode_t calculate_tree(ext2_filsys fs,
11974 struct out_dir *outdir,
11978 struct ext2_dx_root_info *root_info;
11979 struct ext2_dx_entry *root, *dx_ent = 0;
11980 struct ext2_dx_countlimit *root_limit, *limit;
11982 char * block_start;
11983 int i, c1, c2, nblks;
11984 int limit_offset, root_offset;
11986 root_info = set_root_node(fs, outdir->buf, ino, parent);
11987 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
11988 root_info->info_length;
11989 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11990 c1 = root_limit->limit;
11991 nblks = outdir->num;
11993 /* Write out the pointer blocks */
11994 if (nblks-1 <= c1) {
11995 /* Just write out the root block, and we're done */
11996 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
11997 for (i=1; i < nblks; i++) {
11998 root->block = ext2fs_cpu_to_le32(i);
12001 ext2fs_cpu_to_le32(outdir->hashes[i]);
12008 root_info->indirect_levels = 1;
12009 for (i=1; i < nblks; i++) {
12014 limit->limit = limit->count =
12015 ext2fs_cpu_to_le16(limit->limit);
12016 root = (struct ext2_dx_entry *)
12017 (outdir->buf + root_offset);
12018 root->block = ext2fs_cpu_to_le32(outdir->num);
12021 ext2fs_cpu_to_le32(outdir->hashes[i]);
12022 if ((retval = get_next_block(fs, outdir,
12025 dx_ent = set_int_node(fs, block_start);
12026 limit = (struct ext2_dx_countlimit *) dx_ent;
12028 root_offset += sizeof(struct ext2_dx_entry);
12031 dx_ent->block = ext2fs_cpu_to_le32(i);
12032 if (c2 != limit->limit)
12034 ext2fs_cpu_to_le32(outdir->hashes[i]);
12038 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
12039 limit->limit = ext2fs_cpu_to_le16(limit->limit);
12041 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
12042 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
12043 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
12048 struct write_dir_struct {
12049 struct out_dir *outdir;
12056 * Helper function which writes out a directory block.
12058 static int write_dir_block(ext2_filsys fs,
12060 e2_blkcnt_t blockcnt,
12061 blk_t ref_block FSCK_ATTR((unused)),
12062 int ref_offset FSCK_ATTR((unused)),
12065 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
12069 if (*block_nr == 0)
12071 if (blockcnt >= wd->outdir->num) {
12072 e2fsck_read_bitmaps(wd->ctx);
12074 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
12075 ext2fs_block_alloc_stats(fs, blk, -1);
12078 return BLOCK_CHANGED;
12083 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
12084 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
12086 return BLOCK_ABORT;
12090 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
12091 struct out_dir *outdir,
12092 ext2_ino_t ino, int compress)
12094 struct write_dir_struct wd;
12096 struct ext2_inode inode;
12098 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
12102 wd.outdir = outdir;
12107 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12108 write_dir_block, &wd);
12114 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12116 inode.i_flags &= ~EXT2_INDEX_FL;
12118 inode.i_flags |= EXT2_INDEX_FL;
12119 inode.i_size = outdir->num * fs->blocksize;
12120 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
12121 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
12126 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
12128 ext2_filsys fs = ctx->fs;
12130 struct ext2_inode inode;
12132 struct fill_dir_struct fd;
12133 struct out_dir outdir;
12135 outdir.max = outdir.num = 0;
12138 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12142 dir_buf = malloc(inode.i_size);
12146 fd.max_array = inode.i_size / 32;
12148 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
12158 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
12159 (inode.i_size / fs->blocksize) < 2)
12163 /* Read in the entire directory into memory */
12164 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12165 fill_dir_block, &fd);
12171 /* Sort the list */
12174 qsort(fd.harray+2, fd.num_array-2,
12175 sizeof(struct hash_entry), name_cmp);
12177 qsort(fd.harray, fd.num_array,
12178 sizeof(struct hash_entry), hash_cmp);
12181 * Look for duplicates
12183 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
12186 if (ctx->options & E2F_OPT_NO) {
12192 * Copy the directory entries. In a htree directory these
12193 * will become the leaf nodes.
12195 retval = copy_dir_entries(fs, &fd, &outdir);
12199 free(dir_buf); dir_buf = 0;
12201 if (!fd.compress) {
12202 /* Calculate the interior nodes */
12203 retval = calculate_tree(fs, &outdir, ino, fd.parent);
12208 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
12214 free_out_dir(&outdir);
12218 void e2fsck_rehash_directories(e2fsck_t ctx)
12220 struct problem_context pctx;
12221 struct dir_info *dir;
12222 ext2_u32_iterate iter;
12225 int i, cur, max, all_dirs, dir_index, first = 1;
12227 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
12229 if (!ctx->dirs_to_hash && !all_dirs)
12232 e2fsck_get_lost_and_found(ctx, 0);
12234 clear_problem_context(&pctx);
12236 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
12240 max = e2fsck_get_num_dirinfo(ctx);
12242 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
12245 pctx.errcode = retval;
12246 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
12249 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
12253 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
12257 if (!ext2fs_u32_list_iterate(iter, &ino))
12260 if (ino == ctx->lost_and_found)
12264 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
12267 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
12268 if (pctx.errcode) {
12269 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12270 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
12272 if (ctx->progress && !ctx->progress_fd)
12273 e2fsck_simple_progress(ctx, "Rebuilding directory",
12274 100.0 * (float) (++cur) / (float) max, ino);
12276 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12278 ext2fs_u32_list_iterate_end(iter);
12280 ext2fs_u32_list_free(ctx->dirs_to_hash);
12281 ctx->dirs_to_hash = 0;
12285 * linux/fs/revoke.c
12287 * Journal revoke routines for the generic filesystem journaling code;
12288 * part of the ext2fs journaling system.
12290 * Revoke is the mechanism used to prevent old log records for deleted
12291 * metadata from being replayed on top of newer data using the same
12292 * blocks. The revoke mechanism is used in two separate places:
12294 * + Commit: during commit we write the entire list of the current
12295 * transaction's revoked blocks to the journal
12297 * + Recovery: during recovery we record the transaction ID of all
12298 * revoked blocks. If there are multiple revoke records in the log
12299 * for a single block, only the last one counts, and if there is a log
12300 * entry for a block beyond the last revoke, then that log entry still
12303 * We can get interactions between revokes and new log data within a
12304 * single transaction:
12306 * Block is revoked and then journaled:
12307 * The desired end result is the journaling of the new block, so we
12308 * cancel the revoke before the transaction commits.
12310 * Block is journaled and then revoked:
12311 * The revoke must take precedence over the write of the block, so we
12312 * need either to cancel the journal entry or to write the revoke
12313 * later in the log than the log block. In this case, we choose the
12314 * latter: journaling a block cancels any revoke record for that block
12315 * in the current transaction, so any revoke for that block in the
12316 * transaction must have happened after the block was journaled and so
12317 * the revoke must take precedence.
12319 * Block is revoked and then written as data:
12320 * The data write is allowed to succeed, but the revoke is _not_
12321 * cancelled. We still need to prevent old log records from
12322 * overwriting the new data. We don't even need to clear the revoke
12325 * Revoke information on buffers is a tri-state value:
12327 * RevokeValid clear: no cached revoke status, need to look it up
12328 * RevokeValid set, Revoked clear:
12329 * buffer has not been revoked, and cancel_revoke
12331 * RevokeValid set, Revoked set:
12332 * buffer has been revoked.
12335 static kmem_cache_t *revoke_record_cache;
12336 static kmem_cache_t *revoke_table_cache;
12338 /* Each revoke record represents one single revoked block. During
12339 journal replay, this involves recording the transaction ID of the
12340 last transaction to revoke this block. */
12342 struct jbd_revoke_record_s
12344 struct list_head hash;
12345 tid_t sequence; /* Used for recovery only */
12346 unsigned long blocknr;
12350 /* The revoke table is just a simple hash table of revoke records. */
12351 struct jbd_revoke_table_s
12353 /* It is conceivable that we might want a larger hash table
12354 * for recovery. Must be a power of two. */
12357 struct list_head *hash_table;
12361 /* Utility functions to maintain the revoke table */
12363 /* Borrowed from buffer.c: this is a tried and tested block hash function */
12364 static inline int hash(journal_t *journal, unsigned long block)
12366 struct jbd_revoke_table_s *table = journal->j_revoke;
12367 int hash_shift = table->hash_shift;
12369 return ((block << (hash_shift - 6)) ^
12371 (block << (hash_shift - 12))) & (table->hash_size - 1);
12374 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
12377 struct list_head *hash_list;
12378 struct jbd_revoke_record_s *record;
12380 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
12384 record->sequence = seq;
12385 record->blocknr = blocknr;
12386 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
12387 list_add(&record->hash, hash_list);
12394 /* Find a revoke record in the journal's hash table. */
12396 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
12397 unsigned long blocknr)
12399 struct list_head *hash_list;
12400 struct jbd_revoke_record_s *record;
12402 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
12404 record = (struct jbd_revoke_record_s *) hash_list->next;
12405 while (&(record->hash) != hash_list) {
12406 if (record->blocknr == blocknr)
12408 record = (struct jbd_revoke_record_s *) record->hash.next;
12413 int journal_init_revoke_caches(void)
12415 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
12416 if (revoke_record_cache == 0)
12419 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
12420 if (revoke_table_cache == 0) {
12421 do_cache_destroy(revoke_record_cache);
12422 revoke_record_cache = NULL;
12428 void journal_destroy_revoke_caches(void)
12430 do_cache_destroy(revoke_record_cache);
12431 revoke_record_cache = 0;
12432 do_cache_destroy(revoke_table_cache);
12433 revoke_table_cache = 0;
12436 /* Initialise the revoke table for a given journal to a given size. */
12438 int journal_init_revoke(journal_t *journal, int hash_size)
12442 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
12443 if (!journal->j_revoke)
12446 /* Check that the hash_size is a power of two */
12447 journal->j_revoke->hash_size = hash_size;
12451 while((tmp >>= 1UL) != 0UL)
12453 journal->j_revoke->hash_shift = shift;
12455 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
12456 if (!journal->j_revoke->hash_table) {
12457 free(journal->j_revoke);
12458 journal->j_revoke = NULL;
12462 for (tmp = 0; tmp < hash_size; tmp++)
12463 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
12468 /* Destoy a journal's revoke table. The table must already be empty! */
12470 void journal_destroy_revoke(journal_t *journal)
12472 struct jbd_revoke_table_s *table;
12473 struct list_head *hash_list;
12476 table = journal->j_revoke;
12480 for (i=0; i<table->hash_size; i++) {
12481 hash_list = &table->hash_table[i];
12484 free(table->hash_table);
12486 journal->j_revoke = NULL;
12490 * Revoke support for recovery.
12492 * Recovery needs to be able to:
12494 * record all revoke records, including the tid of the latest instance
12495 * of each revoke in the journal
12497 * check whether a given block in a given transaction should be replayed
12498 * (ie. has not been revoked by a revoke record in that or a subsequent
12501 * empty the revoke table after recovery.
12505 * First, setting revoke records. We create a new revoke record for
12506 * every block ever revoked in the log as we scan it for recovery, and
12507 * we update the existing records if we find multiple revokes for a
12511 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
12514 struct jbd_revoke_record_s *record;
12516 record = find_revoke_record(journal, blocknr);
12518 /* If we have multiple occurences, only record the
12519 * latest sequence number in the hashed record */
12520 if (tid_gt(sequence, record->sequence))
12521 record->sequence = sequence;
12524 return insert_revoke_hash(journal, blocknr, sequence);
12528 * Test revoke records. For a given block referenced in the log, has
12529 * that block been revoked? A revoke record with a given transaction
12530 * sequence number revokes all blocks in that transaction and earlier
12531 * ones, but later transactions still need replayed.
12534 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
12537 struct jbd_revoke_record_s *record;
12539 record = find_revoke_record(journal, blocknr);
12542 if (tid_gt(sequence, record->sequence))
12548 * Finally, once recovery is over, we need to clear the revoke table so
12549 * that it can be reused by the running filesystem.
12552 void journal_clear_revoke(journal_t *journal)
12555 struct list_head *hash_list;
12556 struct jbd_revoke_record_s *record;
12557 struct jbd_revoke_table_s *revoke_var;
12559 revoke_var = journal->j_revoke;
12561 for (i = 0; i < revoke_var->hash_size; i++) {
12562 hash_list = &revoke_var->hash_table[i];
12563 while (!list_empty(hash_list)) {
12564 record = (struct jbd_revoke_record_s*) hash_list->next;
12565 list_del(&record->hash);
12572 * e2fsck.c - superblock checks
12575 #define MIN_CHECK 1
12576 #define MAX_CHECK 2
12578 static void check_super_value(e2fsck_t ctx, const char *descr,
12579 unsigned long value, int flags,
12580 unsigned long min_val, unsigned long max_val)
12582 struct problem_context pctx;
12584 if (((flags & MIN_CHECK) && (value < min_val)) ||
12585 ((flags & MAX_CHECK) && (value > max_val))) {
12586 clear_problem_context(&pctx);
12589 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12590 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12595 * This routine may get stubbed out in special compilations of the
12598 #ifndef EXT2_SPECIAL_DEVICE_SIZE
12599 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
12601 return (ext2fs_get_device_size(ctx->filesystem_name,
12602 EXT2_BLOCK_SIZE(ctx->fs->super),
12603 &ctx->num_blocks));
12608 * helper function to release an inode
12610 struct process_block_struct {
12613 struct problem_context *pctx;
12615 int truncate_offset;
12616 e2_blkcnt_t truncate_block;
12617 int truncated_blocks;
12622 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
12623 e2_blkcnt_t blockcnt,
12624 blk_t ref_blk FSCK_ATTR((unused)),
12625 int ref_offset FSCK_ATTR((unused)),
12628 struct process_block_struct *pb;
12630 struct problem_context *pctx;
12631 blk_t blk = *block_nr;
12634 pb = (struct process_block_struct *) priv_data;
12639 pctx->blkcount = blockcnt;
12641 if (HOLE_BLKADDR(blk))
12644 if ((blk < fs->super->s_first_data_block) ||
12645 (blk >= fs->super->s_blocks_count)) {
12646 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
12649 return BLOCK_ABORT;
12652 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
12653 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
12658 * If we are deleting an orphan, then we leave the fields alone.
12659 * If we are truncating an orphan, then update the inode fields
12660 * and clean up any partial block data.
12662 if (pb->truncating) {
12664 * We only remove indirect blocks if they are
12665 * completely empty.
12667 if (blockcnt < 0) {
12671 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
12676 limit = fs->blocksize >> 2;
12677 for (i = 0, bp = (blk_t *) pb->buf;
12678 i < limit; i++, bp++)
12683 * We don't remove direct blocks until we've reached
12684 * the truncation block.
12686 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
12689 * If part of the last block needs truncating, we do
12692 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
12693 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
12697 memset(pb->buf + pb->truncate_offset, 0,
12698 fs->blocksize - pb->truncate_offset);
12699 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
12704 pb->truncated_blocks++;
12706 retval |= BLOCK_CHANGED;
12709 ext2fs_block_alloc_stats(fs, blk, -1);
12714 * This function releases an inode. Returns 1 if an inconsistency was
12715 * found. If the inode has a link count, then it is being truncated and
12718 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
12719 struct ext2_inode *inode, char *block_buf,
12720 struct problem_context *pctx)
12722 struct process_block_struct pb;
12723 ext2_filsys fs = ctx->fs;
12727 if (!ext2fs_inode_has_valid_blocks(inode))
12730 pb.buf = block_buf + 3 * ctx->fs->blocksize;
12735 if (inode->i_links_count) {
12737 pb.truncate_block = (e2_blkcnt_t)
12738 ((((long long)inode->i_size_high << 32) +
12739 inode->i_size + fs->blocksize - 1) /
12741 pb.truncate_offset = inode->i_size % fs->blocksize;
12744 pb.truncate_block = 0;
12745 pb.truncate_offset = 0;
12747 pb.truncated_blocks = 0;
12748 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
12749 block_buf, release_inode_block, &pb);
12751 com_err("release_inode_blocks", retval,
12752 _("while calling ext2fs_block_iterate for inode %d"),
12759 /* Refresh the inode since ext2fs_block_iterate may have changed it */
12760 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
12762 if (pb.truncated_blocks)
12763 inode->i_blocks -= pb.truncated_blocks *
12764 (fs->blocksize / 512);
12766 if (inode->i_file_acl) {
12767 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
12768 block_buf, -1, &count);
12769 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
12774 com_err("release_inode_blocks", retval,
12775 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
12780 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
12781 inode->i_file_acl = 0;
12787 * This function releases all of the orphan inodes. It returns 1 if
12788 * it hit some error, and 0 on success.
12790 static int release_orphan_inodes(e2fsck_t ctx)
12792 ext2_filsys fs = ctx->fs;
12793 ext2_ino_t ino, next_ino;
12794 struct ext2_inode inode;
12795 struct problem_context pctx;
12798 if ((ino = fs->super->s_last_orphan) == 0)
12802 * Win or lose, we won't be using the head of the orphan inode
12805 fs->super->s_last_orphan = 0;
12806 ext2fs_mark_super_dirty(fs);
12809 * If the filesystem contains errors, don't run the orphan
12810 * list, since the orphan list can't be trusted; and we're
12811 * going to be running a full e2fsck run anyway...
12813 if (fs->super->s_state & EXT2_ERROR_FS)
12816 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
12817 (ino > fs->super->s_inodes_count)) {
12818 clear_problem_context(&pctx);
12820 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
12824 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12825 "block iterate buffer");
12826 e2fsck_read_bitmaps(ctx);
12829 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
12830 clear_problem_context(&pctx);
12832 pctx.inode = &inode;
12833 pctx.str = inode.i_links_count ? _("Truncating") :
12836 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
12838 next_ino = inode.i_dtime;
12840 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
12841 (next_ino > fs->super->s_inodes_count))) {
12842 pctx.ino = next_ino;
12843 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
12847 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
12850 if (!inode.i_links_count) {
12851 ext2fs_inode_alloc_stats2(fs, ino, -1,
12852 LINUX_S_ISDIR(inode.i_mode));
12853 inode.i_dtime = time(0);
12857 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
12860 ext2fs_free_mem(&block_buf);
12863 ext2fs_free_mem(&block_buf);
12868 * Check the resize inode to make sure it is sane. We check both for
12869 * the case where on-line resizing is not enabled (in which case the
12870 * resize inode should be cleared) as well as the case where on-line
12871 * resizing is enabled.
12873 static void check_resize_inode(e2fsck_t ctx)
12875 ext2_filsys fs = ctx->fs;
12876 struct ext2_inode inode;
12877 struct problem_context pctx;
12878 int i, j, gdt_off, ind_off;
12879 blk_t blk, pblk, expect;
12880 __u32 *dind_buf = 0, *ind_buf;
12883 clear_problem_context(&pctx);
12886 * If the resize inode feature isn't set, then
12887 * s_reserved_gdt_blocks must be zero.
12889 if (!(fs->super->s_feature_compat &
12890 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12891 if (fs->super->s_reserved_gdt_blocks) {
12892 pctx.num = fs->super->s_reserved_gdt_blocks;
12893 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
12895 fs->super->s_reserved_gdt_blocks = 0;
12896 ext2fs_mark_super_dirty(fs);
12901 /* Read the resize inode */
12902 pctx.ino = EXT2_RESIZE_INO;
12903 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
12905 if (fs->super->s_feature_compat &
12906 EXT2_FEATURE_COMPAT_RESIZE_INODE)
12907 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12912 * If the resize inode feature isn't set, check to make sure
12913 * the resize inode is cleared; then we're done.
12915 if (!(fs->super->s_feature_compat &
12916 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12917 for (i=0; i < EXT2_N_BLOCKS; i++) {
12918 if (inode.i_block[i])
12921 if ((i < EXT2_N_BLOCKS) &&
12922 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
12923 memset(&inode, 0, sizeof(inode));
12924 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12931 * The resize inode feature is enabled; check to make sure the
12932 * only block in use is the double indirect block
12934 blk = inode.i_block[EXT2_DIND_BLOCK];
12935 for (i=0; i < EXT2_N_BLOCKS; i++) {
12936 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
12939 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
12940 !(inode.i_mode & LINUX_S_IFREG) ||
12941 (blk < fs->super->s_first_data_block ||
12942 blk >= fs->super->s_blocks_count)) {
12943 resize_inode_invalid:
12944 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
12945 memset(&inode, 0, sizeof(inode));
12946 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12948 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12950 if (!(ctx->options & E2F_OPT_READONLY)) {
12951 fs->super->s_state &= ~EXT2_VALID_FS;
12952 ext2fs_mark_super_dirty(fs);
12956 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
12957 "resize dind buffer");
12958 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
12960 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
12962 goto resize_inode_invalid;
12964 gdt_off = fs->desc_blocks;
12965 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
12966 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
12967 i++, gdt_off++, pblk++) {
12968 gdt_off %= fs->blocksize/4;
12969 if (dind_buf[gdt_off] != pblk)
12970 goto resize_inode_invalid;
12971 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
12973 goto resize_inode_invalid;
12975 for (j = 1; j < fs->group_desc_count; j++) {
12976 if (!ext2fs_bg_has_super(fs, j))
12978 expect = pblk + (j * fs->super->s_blocks_per_group);
12979 if (ind_buf[ind_off] != expect)
12980 goto resize_inode_invalid;
12986 ext2fs_free_mem(&dind_buf);
12990 static void check_super_block(e2fsck_t ctx)
12992 ext2_filsys fs = ctx->fs;
12993 blk_t first_block, last_block;
12994 struct ext2_super_block *sb = fs->super;
12995 struct ext2_group_desc *gd;
12996 blk_t blocks_per_group = fs->super->s_blocks_per_group;
12998 int inodes_per_block;
13003 struct problem_context pctx;
13004 __u32 free_blocks = 0, free_inodes = 0;
13006 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
13007 ipg_max = inodes_per_block * (blocks_per_group - 4);
13008 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
13009 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
13010 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
13011 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
13012 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
13014 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13015 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
13016 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13017 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
13018 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
13019 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
13021 clear_problem_context(&pctx);
13024 * Verify the super block constants...
13026 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
13028 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
13030 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
13031 MAX_CHECK, 0, sb->s_blocks_count);
13032 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
13033 MIN_CHECK | MAX_CHECK, 0,
13034 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
13035 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
13036 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
13037 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
13038 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
13040 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
13041 MIN_CHECK | MAX_CHECK, 8, bpg_max);
13042 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
13043 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
13044 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
13045 MAX_CHECK, 0, sb->s_blocks_count / 2);
13046 check_super_value(ctx, "reserved_gdt_blocks",
13047 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
13049 inode_size = EXT2_INODE_SIZE(sb);
13050 check_super_value(ctx, "inode_size",
13051 inode_size, MIN_CHECK | MAX_CHECK,
13052 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
13053 if (inode_size & (inode_size - 1)) {
13054 pctx.num = inode_size;
13055 pctx.str = "inode_size";
13056 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13057 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13061 if (!ctx->num_blocks) {
13062 pctx.errcode = e2fsck_get_device_size(ctx);
13063 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
13064 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
13065 ctx->flags |= E2F_FLAG_ABORT;
13068 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
13069 (ctx->num_blocks < sb->s_blocks_count)) {
13070 pctx.blk = sb->s_blocks_count;
13071 pctx.blk2 = ctx->num_blocks;
13072 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
13073 ctx->flags |= E2F_FLAG_ABORT;
13079 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
13080 pctx.blk = EXT2_BLOCK_SIZE(sb);
13081 pctx.blk2 = EXT2_FRAG_SIZE(sb);
13082 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
13083 ctx->flags |= E2F_FLAG_ABORT;
13087 should_be = sb->s_frags_per_group >>
13088 (sb->s_log_block_size - sb->s_log_frag_size);
13089 if (sb->s_blocks_per_group != should_be) {
13090 pctx.blk = sb->s_blocks_per_group;
13091 pctx.blk2 = should_be;
13092 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
13093 ctx->flags |= E2F_FLAG_ABORT;
13097 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
13098 if (sb->s_first_data_block != should_be) {
13099 pctx.blk = sb->s_first_data_block;
13100 pctx.blk2 = should_be;
13101 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
13102 ctx->flags |= E2F_FLAG_ABORT;
13106 should_be = sb->s_inodes_per_group * fs->group_desc_count;
13107 if (sb->s_inodes_count != should_be) {
13108 pctx.ino = sb->s_inodes_count;
13109 pctx.ino2 = should_be;
13110 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
13111 sb->s_inodes_count = should_be;
13112 ext2fs_mark_super_dirty(fs);
13117 * Verify the group descriptors....
13119 first_block = sb->s_first_data_block;
13120 last_block = first_block + blocks_per_group;
13122 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
13125 if (i == fs->group_desc_count - 1)
13126 last_block = sb->s_blocks_count;
13127 if ((gd->bg_block_bitmap < first_block) ||
13128 (gd->bg_block_bitmap >= last_block)) {
13129 pctx.blk = gd->bg_block_bitmap;
13130 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
13131 gd->bg_block_bitmap = 0;
13133 if (gd->bg_block_bitmap == 0) {
13134 ctx->invalid_block_bitmap_flag[i]++;
13135 ctx->invalid_bitmaps++;
13137 if ((gd->bg_inode_bitmap < first_block) ||
13138 (gd->bg_inode_bitmap >= last_block)) {
13139 pctx.blk = gd->bg_inode_bitmap;
13140 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
13141 gd->bg_inode_bitmap = 0;
13143 if (gd->bg_inode_bitmap == 0) {
13144 ctx->invalid_inode_bitmap_flag[i]++;
13145 ctx->invalid_bitmaps++;
13147 if ((gd->bg_inode_table < first_block) ||
13148 ((gd->bg_inode_table +
13149 fs->inode_blocks_per_group - 1) >= last_block)) {
13150 pctx.blk = gd->bg_inode_table;
13151 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
13152 gd->bg_inode_table = 0;
13154 if (gd->bg_inode_table == 0) {
13155 ctx->invalid_inode_table_flag[i]++;
13156 ctx->invalid_bitmaps++;
13158 free_blocks += gd->bg_free_blocks_count;
13159 free_inodes += gd->bg_free_inodes_count;
13160 first_block += sb->s_blocks_per_group;
13161 last_block += sb->s_blocks_per_group;
13163 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
13164 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
13165 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
13166 ext2fs_unmark_valid(fs);
13171 * Update the global counts from the block group counts. This
13172 * is needed for an experimental patch which eliminates
13173 * locking the entire filesystem when allocating blocks or
13174 * inodes; if the filesystem is not unmounted cleanly, the
13175 * global counts may not be accurate.
13177 if ((free_blocks != sb->s_free_blocks_count) ||
13178 (free_inodes != sb->s_free_inodes_count)) {
13179 if (ctx->options & E2F_OPT_READONLY)
13180 ext2fs_unmark_valid(fs);
13182 sb->s_free_blocks_count = free_blocks;
13183 sb->s_free_inodes_count = free_inodes;
13184 ext2fs_mark_super_dirty(fs);
13188 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
13189 (sb->s_free_inodes_count > sb->s_inodes_count))
13190 ext2fs_unmark_valid(fs);
13194 * If we have invalid bitmaps, set the error state of the
13197 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
13198 sb->s_state &= ~EXT2_VALID_FS;
13199 ext2fs_mark_super_dirty(fs);
13202 clear_problem_context(&pctx);
13205 * If the UUID field isn't assigned, assign it.
13207 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
13208 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
13209 uuid_generate(sb->s_uuid);
13210 ext2fs_mark_super_dirty(fs);
13211 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13215 /* FIXME - HURD support?
13216 * For the Hurd, check to see if the filetype option is set,
13217 * since it doesn't support it.
13219 if (!(ctx->options & E2F_OPT_READONLY) &&
13220 fs->super->s_creator_os == EXT2_OS_HURD &&
13221 (fs->super->s_feature_incompat &
13222 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
13223 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
13224 fs->super->s_feature_incompat &=
13225 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
13226 ext2fs_mark_super_dirty(fs);
13232 * If we have any of the compatibility flags set, we need to have a
13233 * revision 1 filesystem. Most kernels will not check the flags on
13234 * a rev 0 filesystem and we may have corruption issues because of
13235 * the incompatible changes to the filesystem.
13237 if (!(ctx->options & E2F_OPT_READONLY) &&
13238 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
13239 (fs->super->s_feature_compat ||
13240 fs->super->s_feature_ro_compat ||
13241 fs->super->s_feature_incompat) &&
13242 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
13243 ext2fs_update_dynamic_rev(fs);
13244 ext2fs_mark_super_dirty(fs);
13247 check_resize_inode(ctx);
13250 * Clean up any orphan inodes, if present.
13252 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
13253 fs->super->s_state &= ~EXT2_VALID_FS;
13254 ext2fs_mark_super_dirty(fs);
13258 * Move the ext3 journal file, if necessary.
13260 e2fsck_move_ext3_journal(ctx);
13265 * swapfs.c --- byte-swap an ext2 filesystem
13268 #ifdef ENABLE_SWAPFS
13270 struct swap_block_struct {
13275 struct ext2_inode *inode;
13279 * This is a helper function for block_iterate. We mark all of the
13280 * indirect and direct blocks as changed, so that block_iterate will
13283 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
13288 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
13290 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
13291 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
13293 sb->errcode = retval;
13294 return BLOCK_ABORT;
13296 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
13298 sb->errcode = retval;
13299 return BLOCK_ABORT;
13302 if (blockcnt >= 0) {
13303 if (blockcnt < EXT2_NDIR_BLOCKS)
13305 return BLOCK_CHANGED;
13307 if (blockcnt == BLOCK_COUNT_IND) {
13308 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
13310 return BLOCK_CHANGED;
13312 if (blockcnt == BLOCK_COUNT_DIND) {
13313 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
13315 return BLOCK_CHANGED;
13317 if (blockcnt == BLOCK_COUNT_TIND) {
13318 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
13320 return BLOCK_CHANGED;
13322 return BLOCK_CHANGED;
13326 * This function is responsible for byte-swapping all of the indirect,
13327 * block pointers. It is also responsible for byte-swapping directories.
13329 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
13330 struct ext2_inode *inode)
13333 struct swap_block_struct sb;
13337 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
13340 if (LINUX_S_ISDIR(inode->i_mode))
13343 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
13346 com_err("swap_inode_blocks", retval,
13347 _("while calling ext2fs_block_iterate"));
13348 ctx->flags |= E2F_FLAG_ABORT;
13352 com_err("swap_inode_blocks", sb.errcode,
13353 _("while calling iterator function"));
13354 ctx->flags |= E2F_FLAG_ABORT;
13359 static void swap_inodes(e2fsck_t ctx)
13361 ext2_filsys fs = ctx->fs;
13364 ext2_ino_t ino = 1;
13365 char *buf, *block_buf;
13367 struct ext2_inode * inode;
13369 e2fsck_use_inode_shortcuts(ctx, 1);
13371 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
13374 com_err("swap_inodes", retval,
13375 _("while allocating inode buffer"));
13376 ctx->flags |= E2F_FLAG_ABORT;
13379 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
13380 "block interate buffer");
13381 for (group = 0; group < fs->group_desc_count; group++) {
13382 retval = io_channel_read_blk(fs->io,
13383 fs->group_desc[group].bg_inode_table,
13384 fs->inode_blocks_per_group, buf);
13386 com_err("swap_inodes", retval,
13387 _("while reading inode table (group %d)"),
13389 ctx->flags |= E2F_FLAG_ABORT;
13392 inode = (struct ext2_inode *) buf;
13393 for (i=0; i < fs->super->s_inodes_per_group;
13394 i++, ino++, inode++) {
13395 ctx->stashed_ino = ino;
13396 ctx->stashed_inode = inode;
13398 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
13399 ext2fs_swap_inode(fs, inode, inode, 0);
13402 * Skip deleted files.
13404 if (inode->i_links_count == 0)
13407 if (LINUX_S_ISDIR(inode->i_mode) ||
13408 ((inode->i_block[EXT2_IND_BLOCK] ||
13409 inode->i_block[EXT2_DIND_BLOCK] ||
13410 inode->i_block[EXT2_TIND_BLOCK]) &&
13411 ext2fs_inode_has_valid_blocks(inode)))
13412 swap_inode_blocks(ctx, ino, block_buf, inode);
13414 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13417 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
13418 ext2fs_swap_inode(fs, inode, inode, 1);
13420 retval = io_channel_write_blk(fs->io,
13421 fs->group_desc[group].bg_inode_table,
13422 fs->inode_blocks_per_group, buf);
13424 com_err("swap_inodes", retval,
13425 _("while writing inode table (group %d)"),
13427 ctx->flags |= E2F_FLAG_ABORT;
13431 ext2fs_free_mem(&buf);
13432 ext2fs_free_mem(&block_buf);
13433 e2fsck_use_inode_shortcuts(ctx, 0);
13434 ext2fs_flush_icache(fs);
13437 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
13439 * On the PowerPC, the big-endian variant of the ext2 filesystem
13440 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
13441 * of each word. Thus a bitmap with only bit 0 set would be, as
13442 * a string of bytes, 00 00 00 01 00 ...
13443 * To cope with this, we byte-reverse each word of a bitmap if
13444 * we have a big-endian filesystem, that is, if we are *not*
13445 * byte-swapping other word-sized numbers.
13447 #define EXT2_BIG_ENDIAN_BITMAPS
13450 #ifdef EXT2_BIG_ENDIAN_BITMAPS
13451 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
13453 __u32 *p = (__u32 *) bmap->bitmap;
13454 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
13456 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
13457 *p = ext2fs_swab32(*p);
13462 #ifdef ENABLE_SWAPFS
13463 static void swap_filesys(e2fsck_t ctx)
13465 ext2_filsys fs = ctx->fs;
13466 if (!(ctx->options & E2F_OPT_PREEN))
13467 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
13471 if (fs->super->s_mnt_count) {
13472 fprintf(stderr, _("%s: the filesystem must be freshly "
13473 "checked using fsck\n"
13474 "and not mounted before trying to "
13475 "byte-swap it.\n"), ctx->device_name);
13476 ctx->flags |= E2F_FLAG_ABORT;
13479 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
13480 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
13481 EXT2_FLAG_SWAP_BYTES_WRITE);
13482 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
13484 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
13485 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
13488 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13490 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
13491 fs->flags |= EXT2_FLAG_SWAP_BYTES;
13492 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
13493 EXT2_FLAG_SWAP_BYTES_WRITE);
13495 #ifdef EXT2_BIG_ENDIAN_BITMAPS
13496 e2fsck_read_bitmaps(ctx);
13497 ext2fs_swap_bitmap(fs->inode_map);
13498 ext2fs_swap_bitmap(fs->block_map);
13499 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
13501 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13503 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13505 #endif /* ENABLE_SWAPFS */
13510 * util.c --- miscellaneous utilities
13514 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
13515 const char *description)
13520 ret = malloc(size);
13522 sprintf(buf, "Can't allocate %s\n", description);
13523 fatal_error(ctx, buf);
13525 memset(ret, 0, size);
13529 static char *string_copy(const char *str, int len)
13537 ret = malloc(len+1);
13539 strncpy(ret, str, len);
13545 #ifndef HAVE_CONIO_H
13546 static int read_a_char(void)
13553 if (e2fsck_global_ctx &&
13554 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
13557 r = read(0, &c, 1);
13567 static int ask_yn(const char * string, int def)
13570 const char *defstr;
13571 static const char short_yes[] = "yY";
13572 static const char short_no[] = "nN";
13574 #ifdef HAVE_TERMIOS_H
13575 struct termios termios, tmp;
13577 tcgetattr (0, &termios);
13579 tmp.c_lflag &= ~(ICANON | ECHO);
13580 tmp.c_cc[VMIN] = 1;
13581 tmp.c_cc[VTIME] = 0;
13582 tcsetattr (0, TCSANOW, &tmp);
13591 printf("%s%s? ", string, defstr);
13594 if ((c = read_a_char()) == EOF)
13597 #ifdef HAVE_TERMIOS_H
13598 tcsetattr (0, TCSANOW, &termios);
13600 if (e2fsck_global_ctx &&
13601 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
13603 longjmp(e2fsck_global_ctx->abort_loc, 1);
13605 puts(_("cancelled!\n"));
13608 if (strchr(short_yes, (char) c)) {
13612 else if (strchr(short_no, (char) c)) {
13616 else if ((c == ' ' || c == '\n') && (def != -1))
13623 #ifdef HAVE_TERMIOS_H
13624 tcsetattr (0, TCSANOW, &termios);
13629 int ask (e2fsck_t ctx, const char * string, int def)
13631 if (ctx->options & E2F_OPT_NO) {
13632 printf (_("%s? no\n\n"), string);
13635 if (ctx->options & E2F_OPT_YES) {
13636 printf (_("%s? yes\n\n"), string);
13639 if (ctx->options & E2F_OPT_PREEN) {
13640 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
13643 return ask_yn(string, def);
13646 void e2fsck_read_bitmaps(e2fsck_t ctx)
13648 ext2_filsys fs = ctx->fs;
13651 if (ctx->invalid_bitmaps) {
13652 com_err(ctx->program_name, 0,
13653 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
13655 fatal_error(ctx, 0);
13658 ehandler_operation(_("reading inode and block bitmaps"));
13659 retval = ext2fs_read_bitmaps(fs);
13660 ehandler_operation(0);
13662 com_err(ctx->program_name, retval,
13663 _("while retrying to read bitmaps for %s"),
13665 fatal_error(ctx, 0);
13669 static void e2fsck_write_bitmaps(e2fsck_t ctx)
13671 ext2_filsys fs = ctx->fs;
13674 if (ext2fs_test_bb_dirty(fs)) {
13675 ehandler_operation(_("writing block bitmaps"));
13676 retval = ext2fs_write_block_bitmap(fs);
13677 ehandler_operation(0);
13679 com_err(ctx->program_name, retval,
13680 _("while retrying to write block bitmaps for %s"),
13682 fatal_error(ctx, 0);
13686 if (ext2fs_test_ib_dirty(fs)) {
13687 ehandler_operation(_("writing inode bitmaps"));
13688 retval = ext2fs_write_inode_bitmap(fs);
13689 ehandler_operation(0);
13691 com_err(ctx->program_name, retval,
13692 _("while retrying to write inode bitmaps for %s"),
13694 fatal_error(ctx, 0);
13699 void preenhalt(e2fsck_t ctx)
13701 ext2_filsys fs = ctx->fs;
13703 if (!(ctx->options & E2F_OPT_PREEN))
13705 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
13706 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
13709 fs->super->s_state |= EXT2_ERROR_FS;
13710 ext2fs_mark_super_dirty(fs);
13713 exit(EXIT_UNCORRECTED);
13716 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
13717 struct ext2_inode * inode, const char *proc)
13721 retval = ext2fs_read_inode(ctx->fs, ino, inode);
13723 com_err("ext2fs_read_inode", retval,
13724 _("while reading inode %ld in %s"), ino, proc);
13725 fatal_error(ctx, 0);
13729 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
13730 struct ext2_inode * inode, int bufsize,
13735 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
13737 com_err("ext2fs_write_inode", retval,
13738 _("while writing inode %ld in %s"), ino, proc);
13739 fatal_error(ctx, 0);
13743 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
13744 struct ext2_inode * inode, const char *proc)
13748 retval = ext2fs_write_inode(ctx->fs, ino, inode);
13750 com_err("ext2fs_write_inode", retval,
13751 _("while writing inode %ld in %s"), ino, proc);
13752 fatal_error(ctx, 0);
13756 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
13757 io_manager manager)
13759 struct ext2_super_block *sb;
13760 io_channel io = NULL;
13763 blk_t superblock, ret_sb = 8193;
13765 if (fs && fs->super) {
13766 ret_sb = (fs->super->s_blocks_per_group +
13767 fs->super->s_first_data_block);
13769 ctx->superblock = ret_sb;
13770 ctx->blocksize = fs->blocksize;
13776 if (ctx->blocksize) {
13777 ret_sb = ctx->blocksize * 8;
13778 if (ctx->blocksize == 1024)
13780 ctx->superblock = ret_sb;
13783 ctx->superblock = ret_sb;
13784 ctx->blocksize = 1024;
13787 if (!name || !manager)
13790 if (manager->open(name, 0, &io) != 0)
13793 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
13795 sb = (struct ext2_super_block *) buf;
13797 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13798 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
13799 superblock = blocksize*8;
13800 if (blocksize == 1024)
13802 io_channel_set_blksize(io, blocksize);
13803 if (io_channel_read_blk(io, superblock,
13804 -SUPERBLOCK_SIZE, buf))
13806 #ifdef EXT2FS_ENABLE_SWAPFS
13807 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
13808 ext2fs_swap_super(sb);
13810 if (sb->s_magic == EXT2_SUPER_MAGIC) {
13811 ret_sb = superblock;
13813 ctx->superblock = superblock;
13814 ctx->blocksize = blocksize;
13822 io_channel_close(io);
13823 ext2fs_free_mem(&buf);
13829 * This function runs through the e2fsck passes and calls them all,
13830 * returning restart, abort, or cancel as necessary...
13832 typedef void (*pass_t)(e2fsck_t ctx);
13834 static const pass_t e2fsck_passes[] = {
13835 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
13838 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
13840 static int e2fsck_run(e2fsck_t ctx)
13843 pass_t e2fsck_pass;
13845 if (setjmp(ctx->abort_loc)) {
13846 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
13847 return (ctx->flags & E2F_FLAG_RUN_RETURN);
13849 ctx->flags |= E2F_FLAG_SETJMP_OK;
13851 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
13852 if (ctx->flags & E2F_FLAG_RUN_RETURN)
13856 (void) (ctx->progress)(ctx, 0, 0, 0);
13858 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
13860 if (ctx->flags & E2F_FLAG_RUN_RETURN)
13861 return (ctx->flags & E2F_FLAG_RUN_RETURN);
13867 * unix.c - The unix-specific code for e2fsck
13871 /* Command line options */
13873 #ifdef ENABLE_SWAPFS
13874 static int normalize_swapfs;
13876 static int cflag; /* check disk */
13877 static int show_version_only;
13878 static int verbose;
13880 static int replace_bad_blocks;
13881 static int keep_bad_blocks;
13882 static char *bad_blocks_file;
13884 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
13886 static void show_stats(e2fsck_t ctx)
13888 ext2_filsys fs = ctx->fs;
13889 int inodes, inodes_used, blocks, blocks_used;
13891 int num_files, num_links;
13894 dir_links = 2 * ctx->fs_directory_count - 1;
13895 num_files = ctx->fs_total_count - dir_links;
13896 num_links = ctx->fs_links_count - dir_links;
13897 inodes = fs->super->s_inodes_count;
13898 inodes_used = (fs->super->s_inodes_count -
13899 fs->super->s_free_inodes_count);
13900 blocks = fs->super->s_blocks_count;
13901 blocks_used = (fs->super->s_blocks_count -
13902 fs->super->s_free_blocks_count);
13904 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
13905 frag_percent = (frag_percent + 5) / 10;
13908 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
13909 ctx->device_name, inodes_used, inodes,
13910 frag_percent / 10, frag_percent % 10,
13911 blocks_used, blocks);
13914 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
13915 100 * inodes_used / inodes);
13916 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
13917 P_E2("", "s", ctx->fs_fragmented),
13918 frag_percent / 10, frag_percent % 10);
13919 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
13920 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
13921 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
13922 (int) ((long long) 100 * blocks_used / blocks));
13923 printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
13924 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
13925 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
13926 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
13927 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
13928 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
13929 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
13930 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
13931 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
13932 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
13933 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
13934 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
13937 static void check_mount(e2fsck_t ctx)
13942 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
13943 &ctx->mount_flags);
13945 com_err("ext2fs_check_if_mount", retval,
13946 _("while determining whether %s is mounted."),
13947 ctx->filesystem_name);
13952 * If the filesystem isn't mounted, or it's the root filesystem
13953 * and it's mounted read-only, then everything's fine.
13955 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
13956 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
13957 (ctx->mount_flags & EXT2_MF_READONLY)))
13960 if (ctx->options & E2F_OPT_READONLY) {
13961 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
13965 printf(_("%s is mounted. "), ctx->filesystem_name);
13966 if (!ctx->interactive)
13967 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
13968 printf(_("\n\n\007\007\007\007WARNING!!! "
13969 "Running e2fsck on a mounted filesystem may cause\n"
13970 "SEVERE filesystem damage.\007\007\007\n\n"));
13971 cont = ask_yn(_("Do you really want to continue"), -1);
13973 printf (_("check aborted.\n"));
13979 static int is_on_batt(void)
13983 char tmp[80], tmp2[80], fname[80];
13984 unsigned int acflag;
13987 f = fopen("/proc/apm", "r");
13989 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
13992 return (acflag != 1);
13994 d = opendir("/proc/acpi/ac_adapter");
13996 while ((de=readdir(d)) != NULL) {
13997 if (!strncmp(".", de->d_name, 1))
13999 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
14001 f = fopen(fname, "r");
14004 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
14007 if (strncmp(tmp, "off-line", 8) == 0) {
14018 * This routine checks to see if a filesystem can be skipped; if so,
14019 * it will exit with EXIT_OK. Under some conditions it will print a
14020 * message explaining why a check is being forced.
14022 static void check_if_skip(e2fsck_t ctx)
14024 ext2_filsys fs = ctx->fs;
14025 const char *reason = NULL;
14026 unsigned int reason_arg = 0;
14028 int batt = is_on_batt();
14029 time_t now = time(0);
14031 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
14035 if ((fs->super->s_state & EXT2_ERROR_FS) ||
14036 !ext2fs_test_valid(fs))
14037 reason = _(" contains a file system with errors");
14038 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
14039 reason = _(" was not cleanly unmounted");
14040 else if ((fs->super->s_max_mnt_count > 0) &&
14041 (fs->super->s_mnt_count >=
14042 (unsigned) fs->super->s_max_mnt_count)) {
14043 reason = _(" has been mounted %u times without being checked");
14044 reason_arg = fs->super->s_mnt_count;
14045 if (batt && (fs->super->s_mnt_count <
14046 (unsigned) fs->super->s_max_mnt_count*2))
14048 } else if (fs->super->s_checkinterval &&
14049 ((now - fs->super->s_lastcheck) >=
14050 fs->super->s_checkinterval)) {
14051 reason = _(" has gone %u days without being checked");
14052 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
14053 if (batt && ((now - fs->super->s_lastcheck) <
14054 fs->super->s_checkinterval*2))
14058 fputs(ctx->device_name, stdout);
14059 printf(reason, reason_arg);
14060 fputs(_(", check forced.\n"), stdout);
14063 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
14064 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
14065 fs->super->s_inodes_count,
14066 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
14067 fs->super->s_blocks_count);
14068 next_check = 100000;
14069 if (fs->super->s_max_mnt_count > 0) {
14070 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
14071 if (next_check <= 0)
14074 if (fs->super->s_checkinterval &&
14075 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
14077 if (next_check <= 5) {
14078 if (next_check == 1)
14079 fputs(_(" (check after next mount)"), stdout);
14081 printf(_(" (check in %ld mounts)"), next_check);
14083 fputc('\n', stdout);
14086 e2fsck_free_context(ctx);
14091 * For completion notice
14093 struct percent_tbl {
14097 static const struct percent_tbl e2fsck_tbl = {
14098 5, { 0, 70, 90, 92, 95, 100 }
14101 static char bar[128], spaces[128];
14103 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
14110 if (pass > tbl->max_pass || max == 0)
14112 percent = ((float) curr) / ((float) max);
14113 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
14114 + tbl->table[pass-1]);
14117 void e2fsck_clear_progbar(e2fsck_t ctx)
14119 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
14122 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
14125 ctx->flags &= ~E2F_FLAG_PROG_BAR;
14128 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
14129 unsigned int dpynum)
14131 static const char spinner[] = "\\|/-";
14138 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
14142 * Calculate the new progress position. If the
14143 * percentage hasn't changed, then we skip out right
14146 fixed_percent = (int) ((10 * percent) + 0.5);
14147 if (ctx->progress_last_percent == fixed_percent)
14149 ctx->progress_last_percent = fixed_percent;
14152 * If we've already updated the spinner once within
14153 * the last 1/8th of a second, no point doing it
14156 gettimeofday(&tv, NULL);
14157 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
14158 if ((tick == ctx->progress_last_time) &&
14159 (fixed_percent != 0) && (fixed_percent != 1000))
14161 ctx->progress_last_time = tick;
14164 * Advance the spinner, and note that the progress bar
14165 * will be on the screen
14167 ctx->progress_pos = (ctx->progress_pos+1) & 3;
14168 ctx->flags |= E2F_FLAG_PROG_BAR;
14170 dpywidth = 66 - strlen(label);
14171 dpywidth = 8 * (dpywidth / 8);
14175 i = ((percent * dpywidth) + 50) / 100;
14176 printf("%s%s: |%s%s", ctx->start_meta, label,
14177 bar + (sizeof(bar) - (i+1)),
14178 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
14179 if (fixed_percent == 1000)
14180 fputc('|', stdout);
14182 fputc(spinner[ctx->progress_pos & 3], stdout);
14183 printf(" %4.1f%% ", percent);
14185 printf("%u\r", dpynum);
14187 fputs(" \r", stdout);
14188 fputs(ctx->stop_meta, stdout);
14190 if (fixed_percent == 1000)
14191 e2fsck_clear_progbar(ctx);
14197 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
14198 unsigned long cur, unsigned long max)
14206 if (ctx->progress_fd) {
14207 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
14208 write(ctx->progress_fd, buf, strlen(buf));
14210 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
14211 e2fsck_simple_progress(ctx, ctx->device_name,
14217 static void reserve_stdio_fds(void)
14222 fd = open(bb_dev_null, O_RDWR);
14226 fprintf(stderr, _("ERROR: Couldn't open "
14227 "/dev/null (%s)\n"),
14235 static void signal_progress_on(int sig FSCK_ATTR((unused)))
14237 e2fsck_t ctx = e2fsck_global_ctx;
14242 ctx->progress = e2fsck_update_progress;
14243 ctx->progress_fd = 0;
14246 static void signal_progress_off(int sig FSCK_ATTR((unused)))
14248 e2fsck_t ctx = e2fsck_global_ctx;
14253 e2fsck_clear_progbar(ctx);
14257 static void signal_cancel(int sig FSCK_ATTR((unused)))
14259 e2fsck_t ctx = e2fsck_global_ctx;
14262 exit(FSCK_CANCELED);
14264 ctx->flags |= E2F_FLAG_CANCEL;
14267 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
14269 char *buf, *token, *next, *p, *arg;
14271 int extended_usage = 0;
14273 buf = string_copy(opts, 0);
14274 for (token = buf; token && *token; token = next) {
14275 p = strchr(token, ',');
14281 arg = strchr(token, '=');
14286 if (strcmp(token, "ea_ver") == 0) {
14291 ea_ver = strtoul(arg, &p, 0);
14293 ((ea_ver != 1) && (ea_ver != 2))) {
14295 _("Invalid EA version.\n"));
14299 ctx->ext_attr_ver = ea_ver;
14301 fprintf(stderr, _("Unknown extended option: %s\n"),
14306 if (extended_usage) {
14307 bb_error_msg_and_die(
14308 "Extended options are separated by commas, "
14309 "and may take an argument which\n"
14310 "is set off by an equals ('=') sign. "
14311 "Valid extended options are:\n"
14312 "\tea_ver=<ea_version (1 or 2)>\n\n");
14317 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
14323 struct sigaction sa;
14324 char *extended_opts = 0;
14326 retval = e2fsck_allocate_context(&ctx);
14332 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
14333 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
14334 if (isatty(0) && isatty(1)) {
14335 ctx->interactive = 1;
14337 ctx->start_meta[0] = '\001';
14338 ctx->stop_meta[0] = '\002';
14340 memset(bar, '=', sizeof(bar)-1);
14341 memset(spaces, ' ', sizeof(spaces)-1);
14342 blkid_get_cache(&ctx->blkid, NULL);
14345 ctx->program_name = *argv;
14347 ctx->program_name = "e2fsck";
14348 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
14351 ctx->progress = e2fsck_update_progress;
14352 ctx->progress_fd = atoi(optarg);
14353 if (!ctx->progress_fd)
14355 /* Validate the file descriptor to avoid disasters */
14356 fd = dup(ctx->progress_fd);
14359 _("Error validating file descriptor %d: %s\n"),
14361 error_message(errno));
14363 _("Invalid completion information file descriptor"));
14368 ctx->options |= E2F_OPT_COMPRESS_DIRS;
14371 extended_opts = optarg;
14375 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
14378 _("Only one the options -p/-a, -n or -y may be specified."));
14380 ctx->options |= E2F_OPT_PREEN;
14383 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
14385 ctx->options |= E2F_OPT_NO;
14388 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
14390 ctx->options |= E2F_OPT_YES;
14393 /* FIXME - This needs to go away in a future path - will change binary */
14394 fprintf(stderr, _("The -t option is not "
14395 "supported on this version of e2fsck.\n"));
14399 ctx->options |= E2F_OPT_WRITECHECK;
14400 ctx->options |= E2F_OPT_CHECKBLOCKS;
14403 /* What we do by default, anyway! */
14406 ctx->use_superblock = atoi(optarg);
14407 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
14410 ctx->blocksize = atoi(optarg);
14413 ctx->inode_buffer_blocks = atoi(optarg);
14416 ctx->journal_name = string_copy(optarg, 0);
14419 ctx->process_inode_size = atoi(optarg);
14422 replace_bad_blocks++;
14424 bad_blocks_file = string_copy(optarg, 0);
14427 ctx->options |= E2F_OPT_DEBUG;
14430 ctx->options |= E2F_OPT_FORCE;
14439 show_version_only = 1;
14442 ctx->device_name = optarg;
14444 #ifdef ENABLE_SWAPFS
14446 normalize_swapfs = 1;
14453 fprintf(stderr, _("Byte-swapping filesystems "
14454 "not compiled in this version "
14464 if (show_version_only)
14466 if (optind != argc - 1)
14468 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
14469 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
14470 ctx->options |= E2F_OPT_READONLY;
14471 ctx->io_options = strchr(argv[optind], '?');
14472 if (ctx->io_options)
14473 *ctx->io_options++ = 0;
14474 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
14475 if (!ctx->filesystem_name) {
14476 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
14478 fatal_error(ctx, 0);
14481 parse_extended_opts(ctx, extended_opts);
14484 fd = open(ctx->filesystem_name, O_RDONLY, 0);
14486 com_err("open", errno,
14487 _("while opening %s for flushing"),
14488 ctx->filesystem_name);
14489 fatal_error(ctx, 0);
14491 if ((retval = ext2fs_sync_device(fd, 1))) {
14492 com_err("ext2fs_sync_device", retval,
14493 _("while trying to flush %s"),
14494 ctx->filesystem_name);
14495 fatal_error(ctx, 0);
14499 #ifdef ENABLE_SWAPFS
14501 if (cflag || bad_blocks_file) {
14502 fprintf(stderr, _("Incompatible options not "
14503 "allowed when byte-swapping.\n"));
14508 if (cflag && bad_blocks_file) {
14509 fprintf(stderr, _("The -c and the -l/-L options may "
14510 "not be both used at the same time.\n"));
14514 * Set up signal action
14516 memset(&sa, 0, sizeof(struct sigaction));
14517 sa.sa_handler = signal_cancel;
14518 sigaction(SIGINT, &sa, 0);
14519 sigaction(SIGTERM, &sa, 0);
14521 sa.sa_flags = SA_RESTART;
14523 e2fsck_global_ctx = ctx;
14524 sa.sa_handler = signal_progress_on;
14525 sigaction(SIGUSR1, &sa, 0);
14526 sa.sa_handler = signal_progress_off;
14527 sigaction(SIGUSR2, &sa, 0);
14529 /* Update our PATH to include /sbin if we need to run badblocks */
14531 e2fs_set_sbin_path();
14535 static const char my_ver_string[] = E2FSPROGS_VERSION;
14536 static const char my_ver_date[] = E2FSPROGS_DATE;
14538 int e2fsck_main (int argc, char *argv[])
14541 int exit_value = EXIT_OK;
14542 ext2_filsys fs = 0;
14544 struct ext2_super_block *sb;
14545 const char *lib_ver_date;
14546 int my_ver, lib_ver;
14548 struct problem_context pctx;
14549 int flags, run_result;
14551 clear_problem_context(&pctx);
14553 my_ver = ext2fs_parse_version_string(my_ver_string);
14554 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
14555 if (my_ver > lib_ver) {
14556 fprintf( stderr, _("Error: ext2fs library version "
14557 "out of date!\n"));
14558 show_version_only++;
14561 retval = PRS(argc, argv, &ctx);
14563 com_err("e2fsck", retval,
14564 _("while trying to initialize program"));
14567 reserve_stdio_fds();
14569 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
14570 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
14573 if (show_version_only) {
14574 fprintf(stderr, _("\tUsing %s, %s\n"),
14575 error_message(EXT2_ET_BASE), lib_ver_date);
14581 if (!(ctx->options & E2F_OPT_PREEN) &&
14582 !(ctx->options & E2F_OPT_NO) &&
14583 !(ctx->options & E2F_OPT_YES)) {
14584 if (!ctx->interactive)
14586 _("need terminal for interactive repairs"));
14588 ctx->superblock = ctx->use_superblock;
14590 #ifdef CONFIG_TESTIO_DEBUG
14591 io_ptr = test_io_manager;
14592 test_io_backing_manager = unix_io_manager;
14594 io_ptr = unix_io_manager;
14597 if ((ctx->options & E2F_OPT_READONLY) == 0)
14598 flags |= EXT2_FLAG_RW;
14600 if (ctx->superblock && ctx->blocksize) {
14601 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
14602 flags, ctx->superblock, ctx->blocksize,
14604 } else if (ctx->superblock) {
14606 for (blocksize = EXT2_MIN_BLOCK_SIZE;
14607 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
14608 retval = ext2fs_open2(ctx->filesystem_name,
14609 ctx->io_options, flags,
14610 ctx->superblock, blocksize,
14616 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
14617 flags, 0, 0, io_ptr, &fs);
14618 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
14619 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
14620 ((retval == EXT2_ET_BAD_MAGIC) ||
14621 ((retval == 0) && ext2fs_check_desc(fs)))) {
14622 if (!fs || (fs->group_desc_count > 1)) {
14623 printf(_("%s trying backup blocks...\n"),
14624 retval ? _("Couldn't find ext2 superblock,") :
14625 _("Group descriptors look bad..."));
14626 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
14633 com_err(ctx->program_name, retval, _("while trying to open %s"),
14634 ctx->filesystem_name);
14635 if (retval == EXT2_ET_REV_TOO_HIGH) {
14636 printf(_("The filesystem revision is apparently "
14637 "too high for this version of e2fsck.\n"
14638 "(Or the filesystem superblock "
14639 "is corrupt)\n\n"));
14640 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
14641 } else if (retval == EXT2_ET_SHORT_READ)
14642 printf(_("Could this be a zero-length partition?\n"));
14643 else if ((retval == EPERM) || (retval == EACCES))
14644 printf(_("You must have %s access to the "
14645 "filesystem or be root\n"),
14646 (ctx->options & E2F_OPT_READONLY) ?
14648 else if (retval == ENXIO)
14649 printf(_("Possibly non-existent or swap device?\n"));
14651 else if (retval == EROFS)
14652 printf(_("Disk write-protected; use the -n option "
14653 "to do a read-only\n"
14654 "check of the device.\n"));
14657 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
14658 fatal_error(ctx, 0);
14661 fs->priv_data = ctx;
14663 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
14664 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
14665 _("while trying to open %s"),
14666 ctx->filesystem_name);
14668 fatal_error(ctx, _("Get a newer version of e2fsck!"));
14672 * Set the device name, which is used whenever we print error
14673 * or informational messages to the user.
14675 if (ctx->device_name == 0 &&
14676 (sb->s_volume_name[0] != 0)) {
14677 ctx->device_name = string_copy(sb->s_volume_name,
14678 sizeof(sb->s_volume_name));
14680 if (ctx->device_name == 0)
14681 ctx->device_name = ctx->filesystem_name;
14684 * Make sure the ext3 superblock fields are consistent.
14686 retval = e2fsck_check_ext3_journal(ctx);
14688 com_err(ctx->program_name, retval,
14689 _("while checking ext3 journal for %s"),
14691 fatal_error(ctx, 0);
14695 * Check to see if we need to do ext3-style recovery. If so,
14696 * do it, and then restart the fsck.
14698 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
14699 if (ctx->options & E2F_OPT_READONLY) {
14700 printf(_("Warning: skipping journal recovery "
14701 "because doing a read-only filesystem "
14703 io_channel_flush(ctx->fs->io);
14705 if (ctx->flags & E2F_FLAG_RESTARTED) {
14707 * Whoops, we attempted to run the
14708 * journal twice. This should never
14709 * happen, unless the hardware or
14710 * device driver is being bogus.
14712 com_err(ctx->program_name, 0,
14713 _("unable to set superblock flags on %s\n"), ctx->device_name);
14714 fatal_error(ctx, 0);
14716 retval = e2fsck_run_ext3_journal(ctx);
14718 com_err(ctx->program_name, retval,
14719 _("while recovering ext3 journal of %s"),
14721 fatal_error(ctx, 0);
14723 ext2fs_close(ctx->fs);
14725 ctx->flags |= E2F_FLAG_RESTARTED;
14731 * Check for compatibility with the feature sets. We need to
14732 * be more stringent than ext2fs_open().
14734 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
14735 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
14736 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
14737 "(%s)", ctx->device_name);
14740 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
14741 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
14742 "(%s)", ctx->device_name);
14745 #ifdef ENABLE_COMPRESSION
14746 /* FIXME - do we support this at all? */
14747 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
14748 com_err(ctx->program_name, 0,
14749 _("Warning: compression support is experimental.\n"));
14751 #ifndef ENABLE_HTREE
14752 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
14753 com_err(ctx->program_name, 0,
14754 _("E2fsck not compiled with HTREE support,\n\t"
14755 "but filesystem %s has HTREE directories.\n"),
14762 * If the user specified a specific superblock, presumably the
14763 * master superblock has been trashed. So we mark the
14764 * superblock as dirty, so it can be written out.
14766 if (ctx->superblock &&
14767 !(ctx->options & E2F_OPT_READONLY))
14768 ext2fs_mark_super_dirty(fs);
14771 * We only update the master superblock because (a) paranoia;
14772 * we don't want to corrupt the backup superblocks, and (b) we
14773 * don't need to update the mount count and last checked
14774 * fields in the backup superblock (the kernel doesn't
14775 * update the backup superblocks anyway).
14777 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
14779 ehandler_init(fs->io);
14781 if (ctx->superblock)
14782 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
14783 ext2fs_mark_valid(fs);
14784 check_super_block(ctx);
14785 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14786 fatal_error(ctx, 0);
14787 check_if_skip(ctx);
14788 if (bad_blocks_file)
14789 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
14791 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
14792 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14793 fatal_error(ctx, 0);
14794 #ifdef ENABLE_SWAPFS
14796 #ifdef WORDS_BIGENDIAN
14797 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
14799 #define NATIVE_FLAG 0
14803 if (normalize_swapfs) {
14804 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
14805 fprintf(stderr, _("%s: Filesystem byte order "
14806 "already normalized.\n"), ctx->device_name);
14807 fatal_error(ctx, 0);
14812 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14813 fatal_error(ctx, 0);
14818 * Mark the system as valid, 'til proven otherwise
14820 ext2fs_mark_valid(fs);
14822 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
14824 com_err(ctx->program_name, retval,
14825 _("while reading bad blocks inode"));
14827 printf(_("This doesn't bode well,"
14828 " but we'll try to go on...\n"));
14831 run_result = e2fsck_run(ctx);
14832 e2fsck_clear_progbar(ctx);
14833 if (run_result == E2F_FLAG_RESTART) {
14834 printf(_("Restarting e2fsck from the beginning...\n"));
14835 retval = e2fsck_reset_context(ctx);
14837 com_err(ctx->program_name, retval,
14838 _("while resetting context"));
14839 fatal_error(ctx, 0);
14844 if (run_result & E2F_FLAG_CANCEL) {
14845 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
14846 ctx->device_name : ctx->filesystem_name);
14847 exit_value |= FSCK_CANCELED;
14849 if (run_result & E2F_FLAG_ABORT)
14850 fatal_error(ctx, _("aborted"));
14853 if (ext2fs_test_changed(fs)) {
14854 exit_value |= EXIT_NONDESTRUCT;
14855 if (!(ctx->options & E2F_OPT_PREEN))
14856 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
14858 if (ctx->mount_flags & EXT2_MF_ISROOT) {
14859 printf(_("%s: ***** REBOOT LINUX *****\n"),
14861 exit_value |= EXIT_DESTRUCT;
14864 if (!ext2fs_test_valid(fs)) {
14865 printf(_("\n%s: ********** WARNING: Filesystem still has "
14866 "errors **********\n\n"), ctx->device_name);
14867 exit_value |= EXIT_UNCORRECTED;
14868 exit_value &= ~EXIT_NONDESTRUCT;
14870 if (exit_value & FSCK_CANCELED)
14871 exit_value &= ~EXIT_NONDESTRUCT;
14874 if (!(ctx->options & E2F_OPT_READONLY)) {
14875 if (ext2fs_test_valid(fs)) {
14876 if (!(sb->s_state & EXT2_VALID_FS))
14877 exit_value |= EXIT_NONDESTRUCT;
14878 sb->s_state = EXT2_VALID_FS;
14880 sb->s_state &= ~EXT2_VALID_FS;
14881 sb->s_mnt_count = 0;
14882 sb->s_lastcheck = time(NULL);
14883 ext2fs_mark_super_dirty(fs);
14887 e2fsck_write_bitmaps(ctx);
14891 free(ctx->filesystem_name);
14892 free(ctx->journal_name);
14893 e2fsck_free_context(ctx);