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);
80 static void print_resource_track(const char *desc,
81 struct resource_track *track);
82 static void init_resource_track(struct resource_track *track);
84 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
85 struct ext2_inode * inode, const char * proc);
86 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
87 struct ext2_inode * inode, const char * proc);
89 static void mtrace_print(char *mesg);
91 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
92 const char *name, io_manager manager);
95 static void e2fsck_clear_progbar(e2fsck_t ctx);
96 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
97 float percent, unsigned int dpynum);
101 * problem.h --- e2fsck problem error codes
104 typedef __u32 problem_t;
106 struct problem_context {
108 ext2_ino_t ino, ino2, dir;
109 struct ext2_inode *inode;
110 struct ext2_dir_entry *dirent;
112 e2_blkcnt_t blkcount;
119 * We define a set of "latch groups"; these are problems which are
120 * handled as a set. The user answers once for a particular latch
123 #define PR_LATCH_MASK 0x0ff0 /* Latch mask */
124 #define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */
125 #define PR_LATCH_BBLOCK 0x0020 /* Latch for bad block inode blocks (pass 1) */
126 #define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */
127 #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */
128 #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */
129 #define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */
130 #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
131 #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */
132 #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */
134 #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1)
137 * Latch group descriptor flags
139 #define PRL_YES 0x0001 /* Answer yes */
140 #define PRL_NO 0x0002 /* Answer no */
141 #define PRL_LATCHED 0x0004 /* The latch group is latched */
142 #define PRL_SUPPRESS 0x0008 /* Suppress all latch group questions */
144 #define PRL_VARIABLE 0x000f /* All the flags that need to be reset */
150 /* Block bitmap not in group */
151 #define PR_0_BB_NOT_GROUP 0x000001
153 /* Inode bitmap not in group */
154 #define PR_0_IB_NOT_GROUP 0x000002
156 /* Inode table not in group */
157 #define PR_0_ITABLE_NOT_GROUP 0x000003
159 /* Superblock corrupt */
160 #define PR_0_SB_CORRUPT 0x000004
162 /* Filesystem size is wrong */
163 #define PR_0_FS_SIZE_WRONG 0x000005
165 /* Fragments not supported */
166 #define PR_0_NO_FRAGMENTS 0x000006
168 /* Bad blocks_per_group */
169 #define PR_0_BLOCKS_PER_GROUP 0x000007
171 /* Bad first_data_block */
172 #define PR_0_FIRST_DATA_BLOCK 0x000008
174 /* Adding UUID to filesystem */
175 #define PR_0_ADD_UUID 0x000009
178 #define PR_0_RELOCATE_HINT 0x00000A
180 /* Miscellaneous superblock corruption */
181 #define PR_0_MISC_CORRUPT_SUPER 0x00000B
183 /* Error determing physical device size of filesystem */
184 #define PR_0_GETSIZE_ERROR 0x00000C
186 /* Inode count in the superblock incorrect */
187 #define PR_0_INODE_COUNT_WRONG 0x00000D
189 /* The Hurd does not support the filetype feature */
190 #define PR_0_HURD_CLEAR_FILETYPE 0x00000E
192 /* Journal inode is invalid */
193 #define PR_0_JOURNAL_BAD_INODE 0x00000F
195 /* The external journal has multiple filesystems (which we can't handle yet) */
196 #define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010
198 /* Can't find external journal */
199 #define PR_0_CANT_FIND_JOURNAL 0x000011
201 /* External journal has bad superblock */
202 #define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012
204 /* Superblock has a bad journal UUID */
205 #define PR_0_JOURNAL_BAD_UUID 0x000013
207 /* Journal has an unknown superblock type */
208 #define PR_0_JOURNAL_UNSUPP_SUPER 0x000014
210 /* Journal superblock is corrupt */
211 #define PR_0_JOURNAL_BAD_SUPER 0x000015
213 /* Journal superblock is corrupt */
214 #define PR_0_JOURNAL_HAS_JOURNAL 0x000016
216 /* Superblock has recovery flag set but no journal */
217 #define PR_0_JOURNAL_RECOVER_SET 0x000017
219 /* Journal has data, but recovery flag is clear */
220 #define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018
222 /* Ask if we should clear the journal */
223 #define PR_0_JOURNAL_RESET_JOURNAL 0x000019
225 /* Filesystem revision is 0, but feature flags are set */
226 #define PR_0_FS_REV_LEVEL 0x00001A
228 /* Clearing orphan inode */
229 #define PR_0_ORPHAN_CLEAR_INODE 0x000020
231 /* Illegal block found in orphaned inode */
232 #define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021
234 /* Already cleared block found in orphaned inode */
235 #define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
237 /* Illegal orphan inode in superblock */
238 #define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023
240 /* Illegal inode in orphaned inode list */
241 #define PR_0_ORPHAN_ILLEGAL_INODE 0x000024
243 /* Journal has unsupported read-only feature - abort */
244 #define PR_0_JOURNAL_UNSUPP_ROCOMPAT 0x000025
246 /* Journal has unsupported incompatible feature - abort */
247 #define PR_0_JOURNAL_UNSUPP_INCOMPAT 0x000026
249 /* Journal has unsupported version number */
250 #define PR_0_JOURNAL_UNSUPP_VERSION 0x000027
252 /* Moving journal to hidden file */
253 #define PR_0_MOVE_JOURNAL 0x000028
255 /* Error moving journal */
256 #define PR_0_ERR_MOVE_JOURNAL 0x000029
258 /* Clearing V2 journal superblock */
259 #define PR_0_CLEAR_V2_JOURNAL 0x00002A
261 /* Run journal anyway */
262 #define PR_0_JOURNAL_RUN 0x00002B
264 /* Run journal anyway by default */
265 #define PR_0_JOURNAL_RUN_DEFAULT 0x00002C
267 /* Backup journal inode blocks */
268 #define PR_0_BACKUP_JNL 0x00002D
270 /* Reserved blocks w/o resize_inode */
271 #define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E
273 /* Resize_inode not enabled, but resize inode is non-zero */
274 #define PR_0_CLEAR_RESIZE_INODE 0x00002F
276 /* Resize inode invalid */
277 #define PR_0_RESIZE_INODE_INVALID 0x000030
283 /* Pass 1: Checking inodes, blocks, and sizes */
284 #define PR_1_PASS_HEADER 0x010000
286 /* Root directory is not an inode */
287 #define PR_1_ROOT_NO_DIR 0x010001
289 /* Root directory has dtime set */
290 #define PR_1_ROOT_DTIME 0x010002
292 /* Reserved inode has bad mode */
293 #define PR_1_RESERVED_BAD_MODE 0x010003
295 /* Deleted inode has zero dtime */
296 #define PR_1_ZERO_DTIME 0x010004
298 /* Inode in use, but dtime set */
299 #define PR_1_SET_DTIME 0x010005
301 /* Zero-length directory */
302 #define PR_1_ZERO_LENGTH_DIR 0x010006
304 /* Block bitmap conflicts with some other fs block */
305 #define PR_1_BB_CONFLICT 0x010007
307 /* Inode bitmap conflicts with some other fs block */
308 #define PR_1_IB_CONFLICT 0x010008
310 /* Inode table conflicts with some other fs block */
311 #define PR_1_ITABLE_CONFLICT 0x010009
313 /* Block bitmap is on a bad block */
314 #define PR_1_BB_BAD_BLOCK 0x01000A
316 /* Inode bitmap is on a bad block */
317 #define PR_1_IB_BAD_BLOCK 0x01000B
319 /* Inode has incorrect i_size */
320 #define PR_1_BAD_I_SIZE 0x01000C
322 /* Inode has incorrect i_blocks */
323 #define PR_1_BAD_I_BLOCKS 0x01000D
325 /* Illegal block number in inode */
326 #define PR_1_ILLEGAL_BLOCK_NUM 0x01000E
328 /* Block number overlaps fs metadata */
329 #define PR_1_BLOCK_OVERLAPS_METADATA 0x01000F
331 /* Inode has illegal blocks (latch question) */
332 #define PR_1_INODE_BLOCK_LATCH 0x010010
334 /* Too many bad blocks in inode */
335 #define PR_1_TOO_MANY_BAD_BLOCKS 0x010011
337 /* Illegal block number in bad block inode */
338 #define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012
340 /* Bad block inode has illegal blocks (latch question) */
341 #define PR_1_INODE_BBLOCK_LATCH 0x010013
343 /* Duplicate or bad blocks in use! */
344 #define PR_1_DUP_BLOCKS_PREENSTOP 0x010014
346 /* Bad block used as bad block indirect block */
347 #define PR_1_BBINODE_BAD_METABLOCK 0x010015
349 /* Inconsistency can't be fixed prompt */
350 #define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
352 /* Bad primary block */
353 #define PR_1_BAD_PRIMARY_BLOCK 0x010017
355 /* Bad primary block prompt */
356 #define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018
358 /* Bad primary superblock */
359 #define PR_1_BAD_PRIMARY_SUPERBLOCK 0x010019
361 /* Bad primary block group descriptors */
362 #define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A
364 /* Bad superblock in group */
365 #define PR_1_BAD_SUPERBLOCK 0x01001B
367 /* Bad block group descriptors in group */
368 #define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C
370 /* Block claimed for no reason */
371 #define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D
373 /* Error allocating blocks for relocating metadata */
374 #define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E
376 /* Error allocating block buffer during relocation process */
377 #define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F
379 /* Relocating metadata group information from X to Y */
380 #define PR_1_RELOC_FROM_TO 0x010020
382 /* Relocating metatdata group information to X */
383 #define PR_1_RELOC_TO 0x010021
385 /* Block read error during relocation process */
386 #define PR_1_RELOC_READ_ERR 0x010022
388 /* Block write error during relocation process */
389 #define PR_1_RELOC_WRITE_ERR 0x010023
391 /* Error allocating inode bitmap */
392 #define PR_1_ALLOCATE_IBITMAP_ERROR 0x010024
394 /* Error allocating block bitmap */
395 #define PR_1_ALLOCATE_BBITMAP_ERROR 0x010025
397 /* Error allocating icount structure */
398 #define PR_1_ALLOCATE_ICOUNT 0x010026
400 /* Error allocating dbcount */
401 #define PR_1_ALLOCATE_DBCOUNT 0x010027
403 /* Error while scanning inodes */
404 #define PR_1_ISCAN_ERROR 0x010028
406 /* Error while iterating over blocks */
407 #define PR_1_BLOCK_ITERATE 0x010029
409 /* Error while storing inode count information */
410 #define PR_1_ICOUNT_STORE 0x01002A
412 /* Error while storing directory block information */
413 #define PR_1_ADD_DBLOCK 0x01002B
415 /* Error while reading inode (for clearing) */
416 #define PR_1_READ_INODE 0x01002C
418 /* Suppress messages prompt */
419 #define PR_1_SUPPRESS_MESSAGES 0x01002D
421 /* Imagic flag set on an inode when filesystem doesn't support it */
422 #define PR_1_SET_IMAGIC 0x01002F
424 /* Immutable flag set on a device or socket inode */
425 #define PR_1_SET_IMMUTABLE 0x010030
427 /* Compression flag set on a non-compressed filesystem */
428 #define PR_1_COMPR_SET 0x010031
430 /* Non-zero size on on device, fifo or socket inode */
431 #define PR_1_SET_NONZSIZE 0x010032
433 /* Filesystem revision is 0, but feature flags are set */
434 #define PR_1_FS_REV_LEVEL 0x010033
436 /* Journal inode not in use, needs clearing */
437 #define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034
439 /* Journal inode has wrong mode */
440 #define PR_1_JOURNAL_BAD_MODE 0x010035
442 /* Inode that was part of orphan linked list */
443 #define PR_1_LOW_DTIME 0x010036
445 /* Latch question which asks how to deal with low dtime inodes */
446 #define PR_1_ORPHAN_LIST_REFUGEES 0x010037
448 /* Error allocating refcount structure */
449 #define PR_1_ALLOCATE_REFCOUNT 0x010038
451 /* Error reading Extended Attribute block */
452 #define PR_1_READ_EA_BLOCK 0x010039
454 /* Invalid Extended Attribute block */
455 #define PR_1_BAD_EA_BLOCK 0x01003A
457 /* Error reading Extended Attribute block while fixing refcount -- abort */
458 #define PR_1_EXTATTR_READ_ABORT 0x01003B
460 /* Extended attribute reference count incorrect */
461 #define PR_1_EXTATTR_REFCOUNT 0x01003C
463 /* Error writing Extended Attribute block while fixing refcount */
464 #define PR_1_EXTATTR_WRITE 0x01003D
466 /* Multiple EA blocks not supported */
467 #define PR_1_EA_MULTI_BLOCK 0x01003E
469 /* Error allocating EA region allocation structure */
470 #define PR_1_EA_ALLOC_REGION 0x01003F
472 /* Error EA allocation collision */
473 #define PR_1_EA_ALLOC_COLLISION 0x010040
475 /* Bad extended attribute name */
476 #define PR_1_EA_BAD_NAME 0x010041
478 /* Bad extended attribute value */
479 #define PR_1_EA_BAD_VALUE 0x010042
481 /* Inode too big (latch question) */
482 #define PR_1_INODE_TOOBIG 0x010043
484 /* Directory too big */
485 #define PR_1_TOOBIG_DIR 0x010044
487 /* Regular file too big */
488 #define PR_1_TOOBIG_REG 0x010045
490 /* Symlink too big */
491 #define PR_1_TOOBIG_SYMLINK 0x010046
493 /* INDEX_FL flag set on a non-HTREE filesystem */
494 #define PR_1_HTREE_SET 0x010047
496 /* INDEX_FL flag set on a non-directory */
497 #define PR_1_HTREE_NODIR 0x010048
499 /* Invalid root node in HTREE directory */
500 #define PR_1_HTREE_BADROOT 0x010049
502 /* Unsupported hash version in HTREE directory */
503 #define PR_1_HTREE_HASHV 0x01004A
505 /* Incompatible flag in HTREE root node */
506 #define PR_1_HTREE_INCOMPAT 0x01004B
509 #define PR_1_HTREE_DEPTH 0x01004C
511 /* Bad block has indirect block that conflicts with filesystem block */
512 #define PR_1_BB_FS_BLOCK 0x01004D
514 /* Resize inode failed */
515 #define PR_1_RESIZE_INODE_CREATE 0x01004E
517 /* inode->i_size is too long */
518 #define PR_1_EXTRA_ISIZE 0x01004F
520 /* attribute name is too long */
521 #define PR_1_ATTR_NAME_LEN 0x010050
523 /* wrong EA value offset */
524 #define PR_1_ATTR_VALUE_OFFSET 0x010051
526 /* wrong EA blocknumber */
527 #define PR_1_ATTR_VALUE_BLOCK 0x010052
529 /* wrong EA value size */
530 #define PR_1_ATTR_VALUE_SIZE 0x010053
532 /* wrong EA hash value */
533 #define PR_1_ATTR_HASH 0x010054
539 /* Pass 1B: Rescan for duplicate/bad blocks */
540 #define PR_1B_PASS_HEADER 0x011000
542 /* Duplicate/bad block(s) header */
543 #define PR_1B_DUP_BLOCK_HEADER 0x011001
545 /* Duplicate/bad block(s) in inode */
546 #define PR_1B_DUP_BLOCK 0x011002
548 /* Duplicate/bad block(s) end */
549 #define PR_1B_DUP_BLOCK_END 0x011003
551 /* Error while scanning inodes */
552 #define PR_1B_ISCAN_ERROR 0x011004
554 /* Error allocating inode bitmap */
555 #define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005
557 /* Error while iterating over blocks */
558 #define PR_1B_BLOCK_ITERATE 0x0110006
560 /* Error adjusting EA refcount */
561 #define PR_1B_ADJ_EA_REFCOUNT 0x0110007
564 /* Pass 1C: Scan directories for inodes with dup blocks. */
565 #define PR_1C_PASS_HEADER 0x012000
568 /* Pass 1D: Reconciling duplicate blocks */
569 #define PR_1D_PASS_HEADER 0x013000
571 /* File has duplicate blocks */
572 #define PR_1D_DUP_FILE 0x013001
574 /* List of files sharing duplicate blocks */
575 #define PR_1D_DUP_FILE_LIST 0x013002
577 /* File sharing blocks with filesystem metadata */
578 #define PR_1D_SHARE_METADATA 0x013003
580 /* Report of how many duplicate/bad inodes */
581 #define PR_1D_NUM_DUP_INODES 0x013004
583 /* Duplicated blocks already reassigned or cloned. */
584 #define PR_1D_DUP_BLOCKS_DEALT 0x013005
586 /* Clone duplicate/bad blocks? */
587 #define PR_1D_CLONE_QUESTION 0x013006
590 #define PR_1D_DELETE_QUESTION 0x013007
592 /* Couldn't clone file (error) */
593 #define PR_1D_CLONE_ERROR 0x013008
599 /* Pass 2: Checking directory structure */
600 #define PR_2_PASS_HEADER 0x020000
602 /* Bad inode number for '.' */
603 #define PR_2_BAD_INODE_DOT 0x020001
605 /* Directory entry has bad inode number */
606 #define PR_2_BAD_INO 0x020002
608 /* Directory entry has deleted or unused inode */
609 #define PR_2_UNUSED_INODE 0x020003
611 /* Directry entry is link to '.' */
612 #define PR_2_LINK_DOT 0x020004
614 /* Directory entry points to inode now located in a bad block */
615 #define PR_2_BB_INODE 0x020005
617 /* Directory entry contains a link to a directory */
618 #define PR_2_LINK_DIR 0x020006
620 /* Directory entry contains a link to the root directry */
621 #define PR_2_LINK_ROOT 0x020007
623 /* Directory entry has illegal characters in its name */
624 #define PR_2_BAD_NAME 0x020008
626 /* Missing '.' in directory inode */
627 #define PR_2_MISSING_DOT 0x020009
629 /* Missing '..' in directory inode */
630 #define PR_2_MISSING_DOT_DOT 0x02000A
632 /* First entry in directory inode doesn't contain '.' */
633 #define PR_2_1ST_NOT_DOT 0x02000B
635 /* Second entry in directory inode doesn't contain '..' */
636 #define PR_2_2ND_NOT_DOT_DOT 0x02000C
638 /* i_faddr should be zero */
639 #define PR_2_FADDR_ZERO 0x02000D
641 /* i_file_acl should be zero */
642 #define PR_2_FILE_ACL_ZERO 0x02000E
644 /* i_dir_acl should be zero */
645 #define PR_2_DIR_ACL_ZERO 0x02000F
647 /* i_frag should be zero */
648 #define PR_2_FRAG_ZERO 0x020010
650 /* i_fsize should be zero */
651 #define PR_2_FSIZE_ZERO 0x020011
653 /* inode has bad mode */
654 #define PR_2_BAD_MODE 0x020012
656 /* directory corrupted */
657 #define PR_2_DIR_CORRUPTED 0x020013
659 /* filename too long */
660 #define PR_2_FILENAME_LONG 0x020014
662 /* Directory inode has a missing block (hole) */
663 #define PR_2_DIRECTORY_HOLE 0x020015
665 /* '.' is not NULL terminated */
666 #define PR_2_DOT_NULL_TERM 0x020016
668 /* '..' is not NULL terminated */
669 #define PR_2_DOT_DOT_NULL_TERM 0x020017
671 /* Illegal character device in inode */
672 #define PR_2_BAD_CHAR_DEV 0x020018
674 /* Illegal block device in inode */
675 #define PR_2_BAD_BLOCK_DEV 0x020019
677 /* Duplicate '.' entry */
678 #define PR_2_DUP_DOT 0x02001A
680 /* Duplicate '..' entry */
681 #define PR_2_DUP_DOT_DOT 0x02001B
683 /* Internal error: couldn't find dir_info */
684 #define PR_2_NO_DIRINFO 0x02001C
686 /* Final rec_len is wrong */
687 #define PR_2_FINAL_RECLEN 0x02001D
689 /* Error allocating icount structure */
690 #define PR_2_ALLOCATE_ICOUNT 0x02001E
692 /* Error iterating over directory blocks */
693 #define PR_2_DBLIST_ITERATE 0x02001F
695 /* Error reading directory block */
696 #define PR_2_READ_DIRBLOCK 0x020020
698 /* Error writing directory block */
699 #define PR_2_WRITE_DIRBLOCK 0x020021
701 /* Error allocating new directory block */
702 #define PR_2_ALLOC_DIRBOCK 0x020022
704 /* Error deallocating inode */
705 #define PR_2_DEALLOC_INODE 0x020023
707 /* Directory entry for '.' is big. Split? */
708 #define PR_2_SPLIT_DOT 0x020024
711 #define PR_2_BAD_FIFO 0x020025
714 #define PR_2_BAD_SOCKET 0x020026
716 /* Directory filetype not set */
717 #define PR_2_SET_FILETYPE 0x020027
719 /* Directory filetype incorrect */
720 #define PR_2_BAD_FILETYPE 0x020028
722 /* Directory filetype set when it shouldn't be */
723 #define PR_2_CLEAR_FILETYPE 0x020029
725 /* Directory filename can't be zero-length */
726 #define PR_2_NULL_NAME 0x020030
728 /* Invalid symlink */
729 #define PR_2_INVALID_SYMLINK 0x020031
731 /* i_file_acl (extended attribute) is bad */
732 #define PR_2_FILE_ACL_BAD 0x020032
734 /* Filesystem contains large files, but has no such flag in sb */
735 #define PR_2_FEATURE_LARGE_FILES 0x020033
737 /* Node in HTREE directory not referenced */
738 #define PR_2_HTREE_NOTREF 0x020034
740 /* Node in HTREE directory referenced twice */
741 #define PR_2_HTREE_DUPREF 0x020035
743 /* Node in HTREE directory has bad min hash */
744 #define PR_2_HTREE_MIN_HASH 0x020036
746 /* Node in HTREE directory has bad max hash */
747 #define PR_2_HTREE_MAX_HASH 0x020037
749 /* Clear invalid HTREE directory */
750 #define PR_2_HTREE_CLEAR 0x020038
752 /* Clear the htree flag forcibly */
753 /* #define PR_2_HTREE_FCLR 0x020039 */
755 /* Bad block in htree interior node */
756 #define PR_2_HTREE_BADBLK 0x02003A
758 /* Error adjusting EA refcount */
759 #define PR_2_ADJ_EA_REFCOUNT 0x02003B
761 /* Invalid HTREE root node */
762 #define PR_2_HTREE_BAD_ROOT 0x02003C
764 /* Invalid HTREE limit */
765 #define PR_2_HTREE_BAD_LIMIT 0x02003D
767 /* Invalid HTREE count */
768 #define PR_2_HTREE_BAD_COUNT 0x02003E
770 /* HTREE interior node has out-of-order hashes in table */
771 #define PR_2_HTREE_HASH_ORDER 0x02003F
773 /* Node in HTREE directory has bad depth */
774 #define PR_2_HTREE_BAD_DEPTH 0x020040
776 /* Duplicate directory entry found */
777 #define PR_2_DUPLICATE_DIRENT 0x020041
779 /* Non-unique filename found */
780 #define PR_2_NON_UNIQUE_FILE 0x020042
782 /* Duplicate directory entry found */
783 #define PR_2_REPORT_DUP_DIRENT 0x020043
789 /* Pass 3: Checking directory connectivity */
790 #define PR_3_PASS_HEADER 0x030000
792 /* Root inode not allocated */
793 #define PR_3_NO_ROOT_INODE 0x030001
795 /* No room in lost+found */
796 #define PR_3_EXPAND_LF_DIR 0x030002
798 /* Unconnected directory inode */
799 #define PR_3_UNCONNECTED_DIR 0x030003
801 /* /lost+found not found */
802 #define PR_3_NO_LF_DIR 0x030004
804 /* .. entry is incorrect */
805 #define PR_3_BAD_DOT_DOT 0x030005
807 /* Bad or non-existent /lost+found. Cannot reconnect */
808 #define PR_3_NO_LPF 0x030006
810 /* Could not expand /lost+found */
811 #define PR_3_CANT_EXPAND_LPF 0x030007
813 /* Could not reconnect inode */
814 #define PR_3_CANT_RECONNECT 0x030008
816 /* Error while trying to find /lost+found */
817 #define PR_3_ERR_FIND_LPF 0x030009
819 /* Error in ext2fs_new_block while creating /lost+found */
820 #define PR_3_ERR_LPF_NEW_BLOCK 0x03000A
822 /* Error in ext2fs_new_inode while creating /lost+found */
823 #define PR_3_ERR_LPF_NEW_INODE 0x03000B
825 /* Error in ext2fs_new_dir_block while creating /lost+found */
826 #define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C
828 /* Error while writing directory block for /lost+found */
829 #define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D
831 /* Error while adjusting inode count */
832 #define PR_3_ADJUST_INODE 0x03000E
834 /* Couldn't fix parent directory -- error */
835 #define PR_3_FIX_PARENT_ERR 0x03000F
837 /* Couldn't fix parent directory -- couldn't find it */
838 #define PR_3_FIX_PARENT_NOFIND 0x030010
840 /* Error allocating inode bitmap */
841 #define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011
843 /* Error creating root directory */
844 #define PR_3_CREATE_ROOT_ERROR 0x030012
846 /* Error creating lost and found directory */
847 #define PR_3_CREATE_LPF_ERROR 0x030013
849 /* Root inode is not directory; aborting */
850 #define PR_3_ROOT_NOT_DIR_ABORT 0x030014
852 /* Cannot proceed without a root inode. */
853 #define PR_3_NO_ROOT_INODE_ABORT 0x030015
855 /* Internal error: couldn't find dir_info */
856 #define PR_3_NO_DIRINFO 0x030016
858 /* Lost+found is not a directory */
859 #define PR_3_LPF_NOTDIR 0x030017
862 * Pass 3a --- rehashing diretories
864 /* Pass 3a: Reindexing directories */
865 #define PR_3A_PASS_HEADER 0x031000
867 /* Error iterating over directories */
868 #define PR_3A_OPTIMIZE_ITER 0x031001
870 /* Error rehash directory */
871 #define PR_3A_OPTIMIZE_DIR_ERR 0x031002
873 /* Rehashing dir header */
874 #define PR_3A_OPTIMIZE_DIR_HEADER 0x031003
876 /* Rehashing directory %d */
877 #define PR_3A_OPTIMIZE_DIR 0x031004
879 /* Rehashing dir end */
880 #define PR_3A_OPTIMIZE_DIR_END 0x031005
886 /* Pass 4: Checking reference counts */
887 #define PR_4_PASS_HEADER 0x040000
889 /* Unattached zero-length inode */
890 #define PR_4_ZERO_LEN_INODE 0x040001
892 /* Unattached inode */
893 #define PR_4_UNATTACHED_INODE 0x040002
895 /* Inode ref count wrong */
896 #define PR_4_BAD_REF_COUNT 0x040003
898 /* Inconsistent inode count information cached */
899 #define PR_4_INCONSISTENT_COUNT 0x040004
905 /* Pass 5: Checking group summary information */
906 #define PR_5_PASS_HEADER 0x050000
908 /* Padding at end of inode bitmap is not set. */
909 #define PR_5_INODE_BMAP_PADDING 0x050001
911 /* Padding at end of block bitmap is not set. */
912 #define PR_5_BLOCK_BMAP_PADDING 0x050002
914 /* Block bitmap differences header */
915 #define PR_5_BLOCK_BITMAP_HEADER 0x050003
917 /* Block not used, but marked in bitmap */
918 #define PR_5_BLOCK_UNUSED 0x050004
920 /* Block used, but not marked used in bitmap */
921 #define PR_5_BLOCK_USED 0x050005
923 /* Block bitmap differences end */
924 #define PR_5_BLOCK_BITMAP_END 0x050006
926 /* Inode bitmap differences header */
927 #define PR_5_INODE_BITMAP_HEADER 0x050007
929 /* Inode not used, but marked in bitmap */
930 #define PR_5_INODE_UNUSED 0x050008
932 /* Inode used, but not marked used in bitmap */
933 #define PR_5_INODE_USED 0x050009
935 /* Inode bitmap differences end */
936 #define PR_5_INODE_BITMAP_END 0x05000A
938 /* Free inodes count for group wrong */
939 #define PR_5_FREE_INODE_COUNT_GROUP 0x05000B
941 /* Directories count for group wrong */
942 #define PR_5_FREE_DIR_COUNT_GROUP 0x05000C
944 /* Free inodes count wrong */
945 #define PR_5_FREE_INODE_COUNT 0x05000D
947 /* Free blocks count for group wrong */
948 #define PR_5_FREE_BLOCK_COUNT_GROUP 0x05000E
950 /* Free blocks count wrong */
951 #define PR_5_FREE_BLOCK_COUNT 0x05000F
953 /* Programming error: bitmap endpoints don't match */
954 #define PR_5_BMAP_ENDPOINTS 0x050010
956 /* Internal error: fudging end of bitmap */
957 #define PR_5_FUDGE_BITMAP_ERROR 0x050011
959 /* Error copying in replacement inode bitmap */
960 #define PR_5_COPY_IBITMAP_ERROR 0x050012
962 /* Error copying in replacement block bitmap */
963 #define PR_5_COPY_BBITMAP_ERROR 0x050013
965 /* Block range not used, but marked in bitmap */
966 #define PR_5_BLOCK_RANGE_UNUSED 0x050014
968 /* Block range used, but not marked used in bitmap */
969 #define PR_5_BLOCK_RANGE_USED 0x050015
971 /* Inode range not used, but marked in bitmap */
972 #define PR_5_INODE_RANGE_UNUSED 0x050016
974 /* Inode rangeused, but not marked used in bitmap */
975 #define PR_5_INODE_RANGE_USED 0x050017
978 * Function declarations
980 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
981 static int end_problem_latch(e2fsck_t ctx, int mask);
982 static int set_latch_flags(int mask, int setflags, int clearflags);
983 static void clear_problem_context(struct problem_context *ctx);
986 * Dictionary Abstract Data Type
987 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
989 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
997 * Blurb for inclusion into C++ translation units
1000 typedef unsigned long dictcount_t;
1001 #define DICTCOUNT_T_MAX ULONG_MAX
1004 * The dictionary is implemented as a red-black tree
1007 typedef enum { dnode_red, dnode_black } dnode_color_t;
1009 typedef struct dnode_t {
1010 struct dnode_t *dict_left;
1011 struct dnode_t *dict_right;
1012 struct dnode_t *dict_parent;
1013 dnode_color_t dict_color;
1014 const void *dict_key;
1018 typedef int (*dict_comp_t)(const void *, const void *);
1019 typedef void (*dnode_free_t)(dnode_t *);
1021 typedef struct dict_t {
1022 dnode_t dict_nilnode;
1023 dictcount_t dict_nodecount;
1024 dictcount_t dict_maxcount;
1025 dict_comp_t dict_compare;
1026 dnode_free_t dict_freenode;
1030 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
1032 typedef struct dict_load_t {
1033 dict_t *dict_dictptr;
1034 dnode_t dict_nilnode;
1037 #define dict_count(D) ((D)->dict_nodecount)
1038 #define dnode_get(N) ((N)->dict_data)
1039 #define dnode_getkey(N) ((N)->dict_key)
1044 * Compatibility header file for e2fsck which should be included
1045 * instead of linux/jfs.h
1047 * Copyright (C) 2000 Stephen C. Tweedie
1051 * Pull in the definition of the e2fsck context structure
1054 struct buffer_head {
1067 #define K_DEV_JOURNAL 2
1069 #define lock_buffer(bh) do {} while(0)
1070 #define unlock_buffer(bh) do {} while(0)
1071 #define buffer_req(bh) 1
1072 #define do_readahead(journal, start) do {} while(0)
1074 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
1080 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
1083 * We use the standard libext2fs portability tricks for inline
1087 static _INLINE_ kmem_cache_t * do_cache_create(int len)
1089 kmem_cache_t *new_cache;
1091 new_cache = malloc(sizeof(*new_cache));
1093 new_cache->object_length = len;
1097 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
1103 * badblocks.c --- replace/append bad blocks to the bad block inode
1106 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
1110 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
1112 printf(_("Bad block %u out of range; ignored.\n"), blk);
1116 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
1117 int replace_bad_blocks)
1119 ext2_filsys fs = ctx->fs;
1121 badblocks_list bb_list = 0;
1125 e2fsck_read_bitmaps(ctx);
1128 * Make sure the bad block inode is sane. If there are any
1129 * illegal blocks, clear them.
1131 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
1132 check_bb_inode_blocks, 0);
1134 com_err("ext2fs_block_iterate", retval,
1135 _("while sanity checking the bad blocks inode"));
1140 * If we're appending to the bad blocks inode, read in the
1141 * current bad blocks.
1143 if (!replace_bad_blocks) {
1144 retval = ext2fs_read_bb_inode(fs, &bb_list);
1146 com_err("ext2fs_read_bb_inode", retval,
1147 _("while reading the bad blocks inode"));
1153 * Now read in the bad blocks from the file; if
1154 * bad_blocks_file is null, then try to run the badblocks
1157 if (bad_blocks_file) {
1158 f = fopen(bad_blocks_file, "r");
1160 com_err("read_bad_blocks_file", errno,
1161 _("while trying to open %s"), bad_blocks_file);
1165 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
1166 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
1167 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
1168 fs->device_name, fs->super->s_blocks_count);
1169 f = popen(buf, "r");
1171 com_err("read_bad_blocks_file", errno,
1172 _("while trying popen '%s'"), buf);
1176 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
1177 if (bad_blocks_file)
1182 com_err("ext2fs_read_bb_FILE", retval,
1183 _("while reading in list of bad blocks from file"));
1188 * Finally, update the bad blocks from the bad_block_map
1190 retval = ext2fs_update_bb_inode(fs, bb_list);
1192 com_err("ext2fs_update_bb_inode", retval,
1193 _("while updating bad block inode"));
1197 ext2fs_badblocks_list_free(bb_list);
1201 ctx->flags |= E2F_FLAG_ABORT;
1206 static int check_bb_inode_blocks(ext2_filsys fs,
1208 int blockcnt FSCK_ATTR((unused)),
1209 void *priv_data FSCK_ATTR((unused)))
1215 * If the block number is outrageous, clear it and ignore it.
1217 if (*block_nr >= fs->super->s_blocks_count ||
1218 *block_nr < fs->super->s_first_data_block) {
1219 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
1221 return BLOCK_CHANGED;
1228 * Dictionary Abstract Data Type
1233 * These macros provide short convenient names for structure members,
1234 * which are embellished with dict_ prefixes so that they are
1235 * properly confined to the documented namespace. It's legal for a
1236 * program which uses dict to define, for instance, a macro called ``parent''.
1237 * Such a macro would interfere with the dnode_t struct definition.
1238 * In general, highly portable and reusable C modules which expose their
1239 * structures need to confine structure member names to well-defined spaces.
1240 * The resulting identifiers aren't necessarily convenient to use, nor
1241 * readable, in the implementation, however!
1244 #define left dict_left
1245 #define right dict_right
1246 #define parent dict_parent
1247 #define color dict_color
1248 #define key dict_key
1249 #define data dict_data
1251 #define nilnode dict_nilnode
1252 #define maxcount dict_maxcount
1253 #define compare dict_compare
1254 #define dupes dict_dupes
1256 #define dict_root(D) ((D)->nilnode.left)
1257 #define dict_nil(D) (&(D)->nilnode)
1258 #define DICT_DEPTH_MAX 64
1260 static void dnode_free(dnode_t *node);
1263 * Perform a ``left rotation'' adjustment on the tree. The given node P and
1264 * its right child C are rearranged so that the P instead becomes the left
1265 * child of C. The left subtree of C is inherited as the new right subtree
1266 * for P. The ordering of the keys within the tree is thus preserved.
1269 static void rotate_left(dnode_t *upper)
1271 dnode_t *lower, *lowleft, *upparent;
1273 lower = upper->right;
1274 upper->right = lowleft = lower->left;
1275 lowleft->parent = upper;
1277 lower->parent = upparent = upper->parent;
1279 /* don't need to check for root node here because root->parent is
1280 the sentinel nil node, and root->parent->left points back to root */
1282 if (upper == upparent->left) {
1283 upparent->left = lower;
1285 assert (upper == upparent->right);
1286 upparent->right = lower;
1289 lower->left = upper;
1290 upper->parent = lower;
1294 * This operation is the ``mirror'' image of rotate_left. It is
1295 * the same procedure, but with left and right interchanged.
1298 static void rotate_right(dnode_t *upper)
1300 dnode_t *lower, *lowright, *upparent;
1302 lower = upper->left;
1303 upper->left = lowright = lower->right;
1304 lowright->parent = upper;
1306 lower->parent = upparent = upper->parent;
1308 if (upper == upparent->right) {
1309 upparent->right = lower;
1311 assert (upper == upparent->left);
1312 upparent->left = lower;
1315 lower->right = upper;
1316 upper->parent = lower;
1320 * Do a postorder traversal of the tree rooted at the specified
1321 * node and free everything under it. Used by dict_free().
1324 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
1328 free_nodes(dict, node->left, nil);
1329 free_nodes(dict, node->right, nil);
1330 dict->dict_freenode(node);
1334 * Verify that the tree contains the given node. This is done by
1335 * traversing all of the nodes and comparing their pointers to the
1336 * given pointer. Returns 1 if the node is found, otherwise
1337 * returns zero. It is intended for debugging purposes.
1340 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
1344 || verify_dict_has_node(nil, root->left, node)
1345 || verify_dict_has_node(nil, root->right, node);
1352 * Select a different set of node allocator routines.
1355 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
1357 assert (dict_count(dict) == 0);
1358 dict->dict_freenode = fr;
1362 * Free all the nodes in the dictionary by using the dictionary's
1363 * installed free routine. The dictionary is emptied.
1366 static void dict_free_nodes(dict_t *dict)
1368 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
1369 free_nodes(dict, root, nil);
1370 dict->dict_nodecount = 0;
1371 dict->nilnode.left = &dict->nilnode;
1372 dict->nilnode.right = &dict->nilnode;
1376 * Initialize a user-supplied dictionary object.
1379 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
1381 dict->compare = comp;
1382 dict->dict_freenode = dnode_free;
1383 dict->dict_nodecount = 0;
1384 dict->maxcount = maxcount;
1385 dict->nilnode.left = &dict->nilnode;
1386 dict->nilnode.right = &dict->nilnode;
1387 dict->nilnode.parent = &dict->nilnode;
1388 dict->nilnode.color = dnode_black;
1394 * Locate a node in the dictionary having the given key.
1395 * If the node is not found, a null a pointer is returned (rather than
1396 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
1397 * located node is returned.
1400 static dnode_t *dict_lookup(dict_t *dict, const void *key)
1402 dnode_t *root = dict_root(dict);
1403 dnode_t *nil = dict_nil(dict);
1407 /* simple binary search adapted for trees that contain duplicate keys */
1409 while (root != nil) {
1410 result = dict->compare(key, root->key);
1413 else if (result > 0)
1416 if (!dict->dupes) { /* no duplicates, return match */
1418 } else { /* could be dupes, find leftmost one */
1422 while (root != nil && dict->compare(key, root->key))
1424 } while (root != nil);
1434 * Insert a node into the dictionary. The node should have been
1435 * initialized with a data field. All other fields are ignored.
1436 * The behavior is undefined if the user attempts to insert into
1437 * a dictionary that is already full (for which the dict_isfull()
1438 * function returns true).
1441 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
1443 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
1444 dnode_t *parent = nil, *uncle, *grandpa;
1449 /* basic binary tree insert */
1451 while (where != nil) {
1453 result = dict->compare(key, where->key);
1454 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
1455 assert (dict->dupes || result != 0);
1457 where = where->left;
1459 where = where->right;
1462 assert (where == nil);
1465 parent->left = node;
1467 parent->right = node;
1469 node->parent = parent;
1473 dict->dict_nodecount++;
1475 /* red black adjustments */
1477 node->color = dnode_red;
1479 while (parent->color == dnode_red) {
1480 grandpa = parent->parent;
1481 if (parent == grandpa->left) {
1482 uncle = grandpa->right;
1483 if (uncle->color == dnode_red) { /* red parent, red uncle */
1484 parent->color = dnode_black;
1485 uncle->color = dnode_black;
1486 grandpa->color = dnode_red;
1488 parent = grandpa->parent;
1489 } else { /* red parent, black uncle */
1490 if (node == parent->right) {
1491 rotate_left(parent);
1493 assert (grandpa == parent->parent);
1494 /* rotation between parent and child preserves grandpa */
1496 parent->color = dnode_black;
1497 grandpa->color = dnode_red;
1498 rotate_right(grandpa);
1501 } else { /* symmetric cases: parent == parent->parent->right */
1502 uncle = grandpa->left;
1503 if (uncle->color == dnode_red) {
1504 parent->color = dnode_black;
1505 uncle->color = dnode_black;
1506 grandpa->color = dnode_red;
1508 parent = grandpa->parent;
1510 if (node == parent->left) {
1511 rotate_right(parent);
1513 assert (grandpa == parent->parent);
1515 parent->color = dnode_black;
1516 grandpa->color = dnode_red;
1517 rotate_left(grandpa);
1523 dict_root(dict)->color = dnode_black;
1528 * Allocate a node using the dictionary's allocator routine, give it
1532 static dnode_t *dnode_init(dnode_t *dnode, void *data)
1535 dnode->parent = NULL;
1537 dnode->right = NULL;
1541 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
1543 dnode_t *node = malloc(sizeof(dnode_t));
1546 dnode_init(node, data);
1547 dict_insert(dict, node, key);
1554 * Return the node with the lowest (leftmost) key. If the dictionary is empty
1555 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
1558 static dnode_t *dict_first(dict_t *dict)
1560 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
1563 while ((left = root->left) != nil)
1566 return (root == nil) ? NULL : root;
1570 * Return the given node's successor node---the node which has the
1571 * next key in the the left to right ordering. If the node has
1572 * no successor, a null pointer is returned rather than a pointer to
1576 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
1578 dnode_t *nil = dict_nil(dict), *parent, *left;
1580 if (curr->right != nil) {
1582 while ((left = curr->left) != nil)
1587 parent = curr->parent;
1589 while (parent != nil && curr == parent->right) {
1591 parent = curr->parent;
1594 return (parent == nil) ? NULL : parent;
1598 static void dnode_free(dnode_t *node)
1618 * dirinfo.c --- maintains the directory information table for e2fsck.
1622 * This subroutine is called during pass1 to create a directory info
1623 * entry. During pass1, the passed-in parent is 0; it will get filled
1626 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
1628 struct dir_info *dir;
1630 ext2_ino_t num_dirs;
1632 unsigned long old_size;
1635 printf("add_dir_info for inode %lu...\n", ino);
1637 if (!ctx->dir_info) {
1638 ctx->dir_info_count = 0;
1639 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
1641 num_dirs = 1024; /* Guess */
1642 ctx->dir_info_size = num_dirs + 10;
1643 ctx->dir_info = (struct dir_info *)
1644 e2fsck_allocate_memory(ctx, ctx->dir_info_size
1645 * sizeof (struct dir_info),
1649 if (ctx->dir_info_count >= ctx->dir_info_size) {
1650 old_size = ctx->dir_info_size * sizeof(struct dir_info);
1651 ctx->dir_info_size += 10;
1652 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
1653 sizeof(struct dir_info),
1656 ctx->dir_info_size -= 10;
1662 * Normally, add_dir_info is called with each inode in
1663 * sequential order; but once in a while (like when pass 3
1664 * needs to recreate the root directory or lost+found
1665 * directory) it is called out of order. In those cases, we
1666 * need to move the dir_info entries down to make room, since
1667 * the dir_info array needs to be sorted by inode number for
1668 * get_dir_info()'s sake.
1670 if (ctx->dir_info_count &&
1671 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
1672 for (i = ctx->dir_info_count-1; i > 0; i--)
1673 if (ctx->dir_info[i-1].ino < ino)
1675 dir = &ctx->dir_info[i];
1676 if (dir->ino != ino)
1677 for (j = ctx->dir_info_count++; j > i; j--)
1678 ctx->dir_info[j] = ctx->dir_info[j-1];
1680 dir = &ctx->dir_info[ctx->dir_info_count++];
1683 dir->dotdot = parent;
1684 dir->parent = parent;
1688 * get_dir_info() --- given an inode number, try to find the directory
1689 * information entry for it.
1691 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
1696 high = ctx->dir_info_count-1;
1699 if (ino == ctx->dir_info[low].ino)
1700 return &ctx->dir_info[low];
1701 if (ino == ctx->dir_info[high].ino)
1702 return &ctx->dir_info[high];
1704 while (low < high) {
1706 if (mid == low || mid == high)
1708 if (ino == ctx->dir_info[mid].ino)
1709 return &ctx->dir_info[mid];
1710 if (ino < ctx->dir_info[mid].ino)
1719 * Free the dir_info structure when it isn't needed any more.
1721 static void e2fsck_free_dir_info(e2fsck_t ctx)
1723 ext2fs_free_mem(&ctx->dir_info);
1724 ctx->dir_info_size = 0;
1725 ctx->dir_info_count = 0;
1729 * Return the count of number of directories in the dir_info structure
1731 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
1733 return ctx->dir_info_count;
1737 * A simple interator function
1739 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
1741 if (*control >= ctx->dir_info_count)
1744 return(ctx->dir_info + (*control)++);
1748 * dirinfo.c --- maintains the directory information table for e2fsck.
1755 * This subroutine is called during pass1 to create a directory info
1756 * entry. During pass1, the passed-in parent is 0; it will get filled
1759 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
1761 struct dx_dir_info *dir;
1764 unsigned long old_size;
1767 printf("add_dx_dir_info for inode %lu...\n", ino);
1769 if (!ctx->dx_dir_info) {
1770 ctx->dx_dir_info_count = 0;
1771 ctx->dx_dir_info_size = 100; /* Guess */
1772 ctx->dx_dir_info = (struct dx_dir_info *)
1773 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
1774 * sizeof (struct dx_dir_info),
1778 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
1779 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
1780 ctx->dx_dir_info_size += 10;
1781 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
1782 sizeof(struct dx_dir_info),
1785 ctx->dx_dir_info_size -= 10;
1791 * Normally, add_dx_dir_info is called with each inode in
1792 * sequential order; but once in a while (like when pass 3
1793 * needs to recreate the root directory or lost+found
1794 * directory) it is called out of order. In those cases, we
1795 * need to move the dx_dir_info entries down to make room, since
1796 * the dx_dir_info array needs to be sorted by inode number for
1797 * get_dx_dir_info()'s sake.
1799 if (ctx->dx_dir_info_count &&
1800 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
1801 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
1802 if (ctx->dx_dir_info[i-1].ino < ino)
1804 dir = &ctx->dx_dir_info[i];
1805 if (dir->ino != ino)
1806 for (j = ctx->dx_dir_info_count++; j > i; j--)
1807 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
1809 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
1812 dir->numblocks = num_blocks;
1813 dir->hashversion = 0;
1814 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
1815 * sizeof (struct dx_dirblock_info),
1816 "dx_block info array");
1821 * get_dx_dir_info() --- given an inode number, try to find the directory
1822 * information entry for it.
1824 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
1829 high = ctx->dx_dir_info_count-1;
1830 if (!ctx->dx_dir_info)
1832 if (ino == ctx->dx_dir_info[low].ino)
1833 return &ctx->dx_dir_info[low];
1834 if (ino == ctx->dx_dir_info[high].ino)
1835 return &ctx->dx_dir_info[high];
1837 while (low < high) {
1839 if (mid == low || mid == high)
1841 if (ino == ctx->dx_dir_info[mid].ino)
1842 return &ctx->dx_dir_info[mid];
1843 if (ino < ctx->dx_dir_info[mid].ino)
1852 * Free the dx_dir_info structure when it isn't needed any more.
1854 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
1857 struct dx_dir_info *dir;
1859 if (ctx->dx_dir_info) {
1860 dir = ctx->dx_dir_info;
1861 for (i=0; i < ctx->dx_dir_info_count; i++) {
1862 ext2fs_free_mem(&dir->dx_block);
1864 ext2fs_free_mem(&ctx->dx_dir_info);
1866 ctx->dx_dir_info_size = 0;
1867 ctx->dx_dir_info_count = 0;
1871 * A simple interator function
1873 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
1875 if (*control >= ctx->dx_dir_info_count)
1878 return(ctx->dx_dir_info + (*control)++);
1881 #endif /* ENABLE_HTREE */
1883 * e2fsck.c - a consistency checker for the new extended file system.
1888 * This function allocates an e2fsck context
1890 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1895 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1899 memset(context, 0, sizeof(struct e2fsck_struct));
1901 context->process_inode_size = 256;
1902 context->ext_attr_ver = 2;
1908 struct ea_refcount_el {
1913 struct ea_refcount {
1917 struct ea_refcount_el *list;
1920 static void ea_refcount_free(ext2_refcount_t refcount)
1925 ext2fs_free_mem(&refcount->list);
1926 ext2fs_free_mem(&refcount);
1930 * This function resets an e2fsck context; it is called when e2fsck
1931 * needs to be restarted.
1933 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1936 ctx->lost_and_found = 0;
1937 ctx->bad_lost_and_found = 0;
1938 ext2fs_free_inode_bitmap(ctx->inode_used_map);
1939 ctx->inode_used_map = 0;
1940 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1941 ctx->inode_dir_map = 0;
1942 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1943 ctx->inode_reg_map = 0;
1944 ext2fs_free_block_bitmap(ctx->block_found_map);
1945 ctx->block_found_map = 0;
1946 ext2fs_free_icount(ctx->inode_link_info);
1947 ctx->inode_link_info = 0;
1948 if (ctx->journal_io) {
1949 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1950 io_channel_close(ctx->journal_io);
1951 ctx->journal_io = 0;
1954 ext2fs_free_dblist(ctx->fs->dblist);
1955 ctx->fs->dblist = 0;
1957 e2fsck_free_dir_info(ctx);
1959 e2fsck_free_dx_dir_info(ctx);
1961 ea_refcount_free(ctx->refcount);
1963 ea_refcount_free(ctx->refcount_extra);
1964 ctx->refcount_extra = 0;
1965 ext2fs_free_block_bitmap(ctx->block_dup_map);
1966 ctx->block_dup_map = 0;
1967 ext2fs_free_block_bitmap(ctx->block_ea_map);
1968 ctx->block_ea_map = 0;
1969 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1970 ctx->inode_bb_map = 0;
1971 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1972 ctx->inode_bad_map = 0;
1973 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1974 ctx->inode_imagic_map = 0;
1975 ext2fs_u32_list_free(ctx->dirs_to_hash);
1976 ctx->dirs_to_hash = 0;
1979 * Clear the array of invalid meta-data flags
1981 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1982 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1983 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1985 /* Clear statistic counters */
1986 ctx->fs_directory_count = 0;
1987 ctx->fs_regular_count = 0;
1988 ctx->fs_blockdev_count = 0;
1989 ctx->fs_chardev_count = 0;
1990 ctx->fs_links_count = 0;
1991 ctx->fs_symlinks_count = 0;
1992 ctx->fs_fast_symlinks_count = 0;
1993 ctx->fs_fifo_count = 0;
1994 ctx->fs_total_count = 0;
1995 ctx->fs_badblocks_count = 0;
1996 ctx->fs_sockets_count = 0;
1997 ctx->fs_ind_count = 0;
1998 ctx->fs_dind_count = 0;
1999 ctx->fs_tind_count = 0;
2000 ctx->fs_fragmented = 0;
2001 ctx->large_files = 0;
2003 /* Reset the superblock to the user's requested value */
2004 ctx->superblock = ctx->use_superblock;
2009 static void e2fsck_free_context(e2fsck_t ctx)
2014 e2fsck_reset_context(ctx);
2016 blkid_put_cache(ctx->blkid);
2018 ext2fs_free_mem(&ctx);
2026 * The strategy we use for keeping track of EA refcounts is as
2027 * follows. We keep a sorted array of first EA blocks and its
2028 * reference counts. Once the refcount has dropped to zero, it is
2029 * removed from the array to save memory space. Once the EA block is
2030 * checked, its bit is set in the block_ea_map bitmap.
2034 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
2036 ext2_refcount_t refcount;
2040 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
2043 memset(refcount, 0, sizeof(struct ea_refcount));
2047 refcount->size = size;
2048 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
2050 printf("Refcount allocated %d entries, %d bytes.\n",
2051 refcount->size, bytes);
2053 retval = ext2fs_get_mem(bytes, &refcount->list);
2056 memset(refcount->list, 0, bytes);
2058 refcount->count = 0;
2059 refcount->cursor = 0;
2065 ea_refcount_free(refcount);
2070 * collapse_refcount() --- go through the refcount array, and get rid
2071 * of any count == zero entries
2073 static void refcount_collapse(ext2_refcount_t refcount)
2076 struct ea_refcount_el *list;
2078 list = refcount->list;
2079 for (i = 0, j = 0; i < refcount->count; i++) {
2080 if (list[i].ea_count) {
2086 #if defined(DEBUG) || defined(TEST_PROGRAM)
2087 printf("Refcount_collapse: size was %d, now %d\n",
2088 refcount->count, j);
2090 refcount->count = j;
2095 * insert_refcount_el() --- Insert a new entry into the sorted list at a
2096 * specified position.
2098 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
2101 struct ea_refcount_el *el;
2106 if (refcount->count >= refcount->size) {
2107 new_size = refcount->size + 100;
2109 printf("Reallocating refcount %d entries...\n", new_size);
2111 retval = ext2fs_resize_mem((size_t) refcount->size *
2112 sizeof(struct ea_refcount_el),
2114 sizeof(struct ea_refcount_el),
2118 refcount->size = new_size;
2120 num = (int) refcount->count - pos;
2122 return 0; /* should never happen */
2124 memmove(&refcount->list[pos+1], &refcount->list[pos],
2125 sizeof(struct ea_refcount_el) * num);
2128 el = &refcount->list[pos];
2136 * get_refcount_el() --- given an block number, try to find refcount
2137 * information in the sorted list. If the create flag is set,
2138 * and we can't find an entry, create one in the sorted list.
2140 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
2141 blk_t blk, int create)
2145 blk_t lowval, highval;
2147 if (!refcount || !refcount->list)
2151 high = (int) refcount->count-1;
2152 if (create && ((refcount->count == 0) ||
2153 (blk > refcount->list[high].ea_blk))) {
2154 if (refcount->count >= refcount->size)
2155 refcount_collapse(refcount);
2157 return insert_refcount_el(refcount, blk,
2158 (unsigned) refcount->count);
2160 if (refcount->count == 0)
2163 if (refcount->cursor >= refcount->count)
2164 refcount->cursor = 0;
2165 if (blk == refcount->list[refcount->cursor].ea_blk)
2166 return &refcount->list[refcount->cursor++];
2168 printf("Non-cursor get_refcount_el: %u\n", blk);
2170 while (low <= high) {
2177 /* Interpolate for efficiency */
2178 lowval = refcount->list[low].ea_blk;
2179 highval = refcount->list[high].ea_blk;
2183 else if (blk > highval)
2186 range = ((float) (blk - lowval)) /
2188 mid = low + ((int) (range * (high-low)));
2191 if (blk == refcount->list[mid].ea_blk) {
2192 refcount->cursor = mid+1;
2193 return &refcount->list[mid];
2195 if (blk < refcount->list[mid].ea_blk)
2201 * If we need to create a new entry, it should be right at
2202 * low (where high will be left at low-1).
2205 if (refcount->count >= refcount->size) {
2206 refcount_collapse(refcount);
2207 if (refcount->count < refcount->size)
2210 return insert_refcount_el(refcount, blk, low);
2216 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
2218 struct ea_refcount_el *el;
2220 el = get_refcount_el(refcount, blk, 1);
2222 return EXT2_ET_NO_MEMORY;
2226 *ret = el->ea_count;
2231 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
2233 struct ea_refcount_el *el;
2235 el = get_refcount_el(refcount, blk, 0);
2236 if (!el || el->ea_count == 0)
2237 return EXT2_ET_INVALID_ARGUMENT;
2242 *ret = el->ea_count;
2247 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
2249 struct ea_refcount_el *el;
2252 * Get the refcount element
2254 el = get_refcount_el(refcount, blk, count ? 1 : 0);
2256 return count ? EXT2_ET_NO_MEMORY : 0;
2257 el->ea_count = count;
2261 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
2263 refcount->cursor = 0;
2267 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
2269 struct ea_refcount_el *list;
2272 if (refcount->cursor >= refcount->count)
2274 list = refcount->list;
2275 if (list[refcount->cursor].ea_count) {
2277 *ret = list[refcount->cursor].ea_count;
2278 return list[refcount->cursor++].ea_blk;
2286 * ehandler.c --- handle bad block errors which come up during the
2287 * course of an e2fsck session.
2291 static const char *operation;
2294 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
2295 void *data, size_t size FSCK_ATTR((unused)),
2296 int actual FSCK_ATTR((unused)), errcode_t error)
2300 ext2_filsys fs = (ext2_filsys) channel->app_data;
2303 ctx = (e2fsck_t) fs->priv_data;
2306 * If more than one block was read, try reading each block
2307 * separately. We could use the actual bytes read to figure
2308 * out where to start, but we don't bother.
2312 for (i=0; i < count; i++, p += channel->block_size, block++) {
2313 error = io_channel_read_blk(channel, block,
2321 printf(_("Error reading block %lu (%s) while %s. "), block,
2322 error_message(error), operation);
2324 printf(_("Error reading block %lu (%s). "), block,
2325 error_message(error));
2327 if (ask(ctx, _("Ignore error"), 1)) {
2328 if (ask(ctx, _("Force rewrite"), 1))
2329 io_channel_write_blk(channel, block, 1, data);
2337 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
2338 const void *data, size_t size FSCK_ATTR((unused)),
2339 int actual FSCK_ATTR((unused)), errcode_t error)
2343 ext2_filsys fs = (ext2_filsys) channel->app_data;
2346 ctx = (e2fsck_t) fs->priv_data;
2349 * If more than one block was written, try writing each block
2350 * separately. We could use the actual bytes read to figure
2351 * out where to start, but we don't bother.
2354 p = (const char *) data;
2355 for (i=0; i < count; i++, p += channel->block_size, block++) {
2356 error = io_channel_write_blk(channel, block,
2365 printf(_("Error writing block %lu (%s) while %s. "), block,
2366 error_message(error), operation);
2368 printf(_("Error writing block %lu (%s). "), block,
2369 error_message(error));
2371 if (ask(ctx, _("Ignore error"), 1))
2377 static inline const char *ehandler_operation(const char *op)
2379 const char *ret = operation;
2385 static void ehandler_init(io_channel channel)
2387 channel->read_error = e2fsck_handle_read_error;
2388 channel->write_error = e2fsck_handle_write_error;
2392 * journal.c --- code for handling the "ext3" journal
2394 * Copyright (C) 2000 Andreas Dilger
2395 * Copyright (C) 2000 Theodore Ts'o
2397 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
2398 * Copyright (C) 1999 Red Hat Software
2400 * This file may be redistributed under the terms of the
2401 * GNU General Public License version 2 or at your discretion
2402 * any later version.
2405 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
2408 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
2409 * This creates a larger static binary, and a smaller binary using
2410 * shared libraries. It's also probably slightly less CPU-efficient,
2411 * which is why it's not on by default. But, it's a good way of
2412 * testing the functions in inode_io.c and fileio.c.
2416 /* Kernel compatibility functions for handling the journal. These allow us
2417 * to use the recovery.c file virtually unchanged from the kernel, so we
2418 * don't have to do much to keep kernel and user recovery in sync.
2420 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
2426 struct inode *inode = journal->j_inode;
2435 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
2436 &inode->i_ext2, NULL, 0, block, &pblk);
2442 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
2444 struct buffer_head *bh;
2446 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
2450 bh->b_ctx = kdev->k_ctx;
2451 if (kdev->k_dev == K_DEV_FS)
2452 bh->b_io = kdev->k_ctx->fs->io;
2454 bh->b_io = kdev->k_ctx->journal_io;
2455 bh->b_size = blocksize;
2456 bh->b_blocknr = blocknr;
2461 static void sync_blockdev(kdev_t kdev)
2465 if (kdev->k_dev == K_DEV_FS)
2466 io = kdev->k_ctx->fs->io;
2468 io = kdev->k_ctx->journal_io;
2470 io_channel_flush(io);
2473 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
2476 struct buffer_head *bh;
2478 for (; nr > 0; --nr) {
2480 if (rw == READ && !bh->b_uptodate) {
2481 retval = io_channel_read_blk(bh->b_io,
2485 com_err(bh->b_ctx->device_name, retval,
2486 "while reading block %lu\n",
2487 (unsigned long) bh->b_blocknr);
2492 } else if (rw == WRITE && bh->b_dirty) {
2493 retval = io_channel_write_blk(bh->b_io,
2497 com_err(bh->b_ctx->device_name, retval,
2498 "while writing block %lu\n",
2499 (unsigned long) bh->b_blocknr);
2509 static inline void mark_buffer_dirty(struct buffer_head *bh)
2514 static inline void mark_buffer_clean(struct buffer_head * bh)
2519 static void brelse(struct buffer_head *bh)
2522 ll_rw_block(WRITE, 1, &bh);
2523 ext2fs_free_mem(&bh);
2526 static inline int buffer_uptodate(struct buffer_head *bh)
2528 return bh->b_uptodate;
2531 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
2533 bh->b_uptodate = val;
2536 static void wait_on_buffer(struct buffer_head *bh)
2538 if (!bh->b_uptodate)
2539 ll_rw_block(READ, 1, &bh);
2543 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
2545 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
2547 /* if we had an error doing journal recovery, we need a full fsck */
2549 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
2550 ext2fs_mark_super_dirty(ctx->fs);
2553 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
2555 struct ext2_super_block *sb = ctx->fs->super;
2556 struct ext2_super_block jsuper;
2557 struct problem_context pctx;
2558 struct buffer_head *bh;
2559 struct inode *j_inode = NULL;
2560 struct kdev_s *dev_fs = NULL, *dev_journal;
2561 const char *journal_name = 0;
2562 journal_t *journal = NULL;
2563 errcode_t retval = 0;
2564 io_manager io_ptr = 0;
2565 unsigned long start = 0;
2567 int ext_journal = 0;
2568 int tried_backup_jnl = 0;
2571 clear_problem_context(&pctx);
2573 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
2575 return EXT2_ET_NO_MEMORY;
2578 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
2580 retval = EXT2_ET_NO_MEMORY;
2583 dev_journal = dev_fs+1;
2585 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
2586 dev_fs->k_dev = K_DEV_FS;
2587 dev_journal->k_dev = K_DEV_JOURNAL;
2589 journal->j_dev = dev_journal;
2590 journal->j_fs_dev = dev_fs;
2591 journal->j_inode = NULL;
2592 journal->j_blocksize = ctx->fs->blocksize;
2594 if (uuid_is_null(sb->s_journal_uuid)) {
2595 if (!sb->s_journal_inum)
2596 return EXT2_ET_BAD_INODE_NUM;
2597 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
2600 retval = EXT2_ET_NO_MEMORY;
2604 j_inode->i_ctx = ctx;
2605 j_inode->i_ino = sb->s_journal_inum;
2607 if ((retval = ext2fs_read_inode(ctx->fs,
2609 &j_inode->i_ext2))) {
2611 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
2614 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
2615 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
2617 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
2618 j_inode->i_ext2.i_links_count = 1;
2619 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
2622 if (!j_inode->i_ext2.i_links_count ||
2623 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
2624 retval = EXT2_ET_NO_JOURNAL;
2625 goto try_backup_journal;
2627 if (j_inode->i_ext2.i_size / journal->j_blocksize <
2628 JFS_MIN_JOURNAL_BLOCKS) {
2629 retval = EXT2_ET_JOURNAL_TOO_SMALL;
2630 goto try_backup_journal;
2632 for (i=0; i < EXT2_N_BLOCKS; i++) {
2633 blk = j_inode->i_ext2.i_block[i];
2635 if (i < EXT2_NDIR_BLOCKS) {
2636 retval = EXT2_ET_JOURNAL_TOO_SMALL;
2637 goto try_backup_journal;
2641 if (blk < sb->s_first_data_block ||
2642 blk >= sb->s_blocks_count) {
2643 retval = EXT2_ET_BAD_BLOCK_NUM;
2644 goto try_backup_journal;
2647 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
2650 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
2656 io_ptr = inode_io_manager;
2658 journal->j_inode = j_inode;
2659 ctx->journal_io = ctx->fs->io;
2660 if ((retval = journal_bmap(journal, 0, &start)) != 0)
2665 if (!ctx->journal_name) {
2668 uuid_unparse(sb->s_journal_uuid, uuid);
2669 ctx->journal_name = blkid_get_devname(ctx->blkid,
2671 if (!ctx->journal_name)
2672 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
2674 journal_name = ctx->journal_name;
2676 if (!journal_name) {
2677 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
2678 return EXT2_ET_LOAD_EXT_JOURNAL;
2681 io_ptr = unix_io_manager;
2684 #ifndef USE_INODE_IO
2687 retval = io_ptr->open(journal_name, IO_FLAG_RW,
2692 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
2695 if (ctx->fs->blocksize == 1024)
2697 bh = getblk(dev_journal, start, ctx->fs->blocksize);
2699 retval = EXT2_ET_NO_MEMORY;
2702 ll_rw_block(READ, 1, &bh);
2703 if ((retval = bh->b_err) != 0)
2705 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
2708 #ifdef EXT2FS_ENABLE_SWAPFS
2709 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
2710 ext2fs_swap_super(&jsuper);
2712 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
2713 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
2714 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
2715 retval = EXT2_ET_LOAD_EXT_JOURNAL;
2718 /* Make sure the journal UUID is correct */
2719 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
2720 sizeof(jsuper.s_uuid))) {
2721 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
2722 retval = EXT2_ET_LOAD_EXT_JOURNAL;
2726 journal->j_maxlen = jsuper.s_blocks_count;
2730 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
2731 retval = EXT2_ET_NO_MEMORY;
2735 journal->j_sb_buffer = bh;
2736 journal->j_superblock = (journal_superblock_t *)bh->b_data;
2739 ext2fs_free_mem(&j_inode);
2742 *ret_journal = journal;
2746 ext2fs_free_mem(&dev_fs);
2747 ext2fs_free_mem(&j_inode);
2748 ext2fs_free_mem(&journal);
2753 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
2754 struct problem_context *pctx)
2756 struct ext2_super_block *sb = ctx->fs->super;
2757 int recover = ctx->fs->super->s_feature_incompat &
2758 EXT3_FEATURE_INCOMPAT_RECOVER;
2759 int has_journal = ctx->fs->super->s_feature_compat &
2760 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2762 if (has_journal || sb->s_journal_inum) {
2763 /* The journal inode is bogus, remove and force full fsck */
2764 pctx->ino = sb->s_journal_inum;
2765 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
2766 if (has_journal && sb->s_journal_inum)
2767 printf("*** ext3 journal has been deleted - "
2768 "filesystem is now ext2 only ***\n\n");
2769 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2770 sb->s_journal_inum = 0;
2771 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
2772 e2fsck_clear_recover(ctx, 1);
2775 return EXT2_ET_BAD_INODE_NUM;
2776 } else if (recover) {
2777 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
2778 e2fsck_clear_recover(ctx, 1);
2781 return EXT2_ET_UNSUPP_FEATURE;
2786 #define V1_SB_SIZE 0x0024
2787 static void clear_v2_journal_fields(journal_t *journal)
2789 e2fsck_t ctx = journal->j_dev->k_ctx;
2790 struct problem_context pctx;
2792 clear_problem_context(&pctx);
2794 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
2797 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
2798 ctx->fs->blocksize-V1_SB_SIZE);
2799 mark_buffer_dirty(journal->j_sb_buffer);
2803 static errcode_t e2fsck_journal_load(journal_t *journal)
2805 e2fsck_t ctx = journal->j_dev->k_ctx;
2806 journal_superblock_t *jsb;
2807 struct buffer_head *jbh = journal->j_sb_buffer;
2808 struct problem_context pctx;
2810 clear_problem_context(&pctx);
2812 ll_rw_block(READ, 1, &jbh);
2814 com_err(ctx->device_name, jbh->b_err,
2815 _("reading journal superblock\n"));
2819 jsb = journal->j_superblock;
2820 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
2821 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
2822 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2824 switch (ntohl(jsb->s_header.h_blocktype)) {
2825 case JFS_SUPERBLOCK_V1:
2826 journal->j_format_version = 1;
2827 if (jsb->s_feature_compat ||
2828 jsb->s_feature_incompat ||
2829 jsb->s_feature_ro_compat ||
2831 clear_v2_journal_fields(journal);
2834 case JFS_SUPERBLOCK_V2:
2835 journal->j_format_version = 2;
2836 if (ntohl(jsb->s_nr_users) > 1 &&
2837 uuid_is_null(ctx->fs->super->s_journal_uuid))
2838 clear_v2_journal_fields(journal);
2839 if (ntohl(jsb->s_nr_users) > 1) {
2840 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
2841 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
2846 * These should never appear in a journal super block, so if
2847 * they do, the journal is badly corrupted.
2849 case JFS_DESCRIPTOR_BLOCK:
2850 case JFS_COMMIT_BLOCK:
2851 case JFS_REVOKE_BLOCK:
2852 return EXT2_ET_CORRUPT_SUPERBLOCK;
2854 /* If we don't understand the superblock major type, but there
2855 * is a magic number, then it is likely to be a new format we
2856 * just don't understand, so leave it alone. */
2858 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
2861 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
2862 return EXT2_ET_UNSUPP_FEATURE;
2864 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
2865 return EXT2_ET_RO_UNSUPP_FEATURE;
2867 /* We have now checked whether we know enough about the journal
2868 * format to be able to proceed safely, so any other checks that
2869 * fail we should attempt to recover from. */
2870 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
2871 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2872 _("%s: no valid journal superblock found\n"),
2874 return EXT2_ET_CORRUPT_SUPERBLOCK;
2877 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
2878 journal->j_maxlen = ntohl(jsb->s_maxlen);
2879 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
2880 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2881 _("%s: journal too short\n"),
2883 return EXT2_ET_CORRUPT_SUPERBLOCK;
2886 journal->j_tail_sequence = ntohl(jsb->s_sequence);
2887 journal->j_transaction_sequence = journal->j_tail_sequence;
2888 journal->j_tail = ntohl(jsb->s_start);
2889 journal->j_first = ntohl(jsb->s_first);
2890 journal->j_last = ntohl(jsb->s_maxlen);
2895 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2906 /* Leave a valid existing V1 superblock signature alone.
2907 * Anything unrecognisable we overwrite with a new V2
2910 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2911 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2912 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2913 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2916 /* Zero out everything else beyond the superblock header */
2918 p = ((char *) jsb) + sizeof(journal_header_t);
2919 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2921 jsb->s_blocksize = htonl(ctx->fs->blocksize);
2922 jsb->s_maxlen = htonl(journal->j_maxlen);
2923 jsb->s_first = htonl(1);
2925 /* Initialize the journal sequence number so that there is "no"
2926 * chance we will find old "valid" transactions in the journal.
2927 * This avoids the need to zero the whole journal (slow to do,
2928 * and risky when we are just recovering the filesystem).
2930 uuid_generate(u.uuid);
2931 for (i = 0; i < 4; i ++)
2932 new_seq ^= u.val[i];
2933 jsb->s_sequence = htonl(new_seq);
2935 mark_buffer_dirty(journal->j_sb_buffer);
2936 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2939 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2941 struct problem_context *pctx)
2943 struct ext2_super_block *sb = ctx->fs->super;
2944 int recover = ctx->fs->super->s_feature_incompat &
2945 EXT3_FEATURE_INCOMPAT_RECOVER;
2947 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2948 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2949 e2fsck_journal_reset_super(ctx, journal->j_superblock,
2951 journal->j_transaction_sequence = 1;
2952 e2fsck_clear_recover(ctx, recover);
2955 return EXT2_ET_CORRUPT_SUPERBLOCK;
2956 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2957 return EXT2_ET_CORRUPT_SUPERBLOCK;
2962 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2963 int reset, int drop)
2965 journal_superblock_t *jsb;
2968 mark_buffer_clean(journal->j_sb_buffer);
2969 else if (!(ctx->options & E2F_OPT_READONLY)) {
2970 jsb = journal->j_superblock;
2971 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2973 jsb->s_start = 0; /* this marks the journal as empty */
2974 mark_buffer_dirty(journal->j_sb_buffer);
2976 brelse(journal->j_sb_buffer);
2978 if (ctx->journal_io) {
2979 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2980 io_channel_close(ctx->journal_io);
2981 ctx->journal_io = 0;
2984 #ifndef USE_INODE_IO
2985 ext2fs_free_mem(&journal->j_inode);
2987 ext2fs_free_mem(&journal->j_fs_dev);
2988 ext2fs_free_mem(&journal);
2992 * This function makes sure that the superblock fields regarding the
2993 * journal are consistent.
2995 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2997 struct ext2_super_block *sb = ctx->fs->super;
2999 int recover = ctx->fs->super->s_feature_incompat &
3000 EXT3_FEATURE_INCOMPAT_RECOVER;
3001 struct problem_context pctx;
3003 int reset = 0, force_fsck = 0;
3006 /* If we don't have any journal features, don't do anything more */
3007 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3008 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
3009 uuid_is_null(sb->s_journal_uuid))
3012 clear_problem_context(&pctx);
3013 pctx.num = sb->s_journal_inum;
3015 retval = e2fsck_get_journal(ctx, &journal);
3017 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
3018 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
3019 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
3020 (retval == EXT2_ET_NO_JOURNAL))
3021 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3025 retval = e2fsck_journal_load(journal);
3027 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
3028 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
3029 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
3031 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
3032 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
3034 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
3035 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
3036 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
3038 e2fsck_journal_release(ctx, journal, 0, 1);
3043 * We want to make the flags consistent here. We will not leave with
3044 * needs_recovery set but has_journal clear. We can't get in a loop
3045 * with -y, -n, or -p, only if a user isn't making up their mind.
3048 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
3049 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
3051 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
3053 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
3054 goto no_has_journal;
3056 * Need a full fsck if we are releasing a
3057 * journal stored on a reserved inode.
3059 force_fsck = recover ||
3060 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
3061 /* Clear all of the journal fields */
3062 sb->s_journal_inum = 0;
3063 sb->s_journal_dev = 0;
3064 memset(sb->s_journal_uuid, 0,
3065 sizeof(sb->s_journal_uuid));
3066 e2fsck_clear_recover(ctx, force_fsck);
3067 } else if (!(ctx->options & E2F_OPT_READONLY)) {
3068 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3069 ext2fs_mark_super_dirty(ctx->fs);
3073 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
3074 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
3075 journal->j_superblock->s_start != 0) {
3076 /* Print status information */
3077 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
3078 if (ctx->superblock)
3079 problem = PR_0_JOURNAL_RUN_DEFAULT;
3081 problem = PR_0_JOURNAL_RUN;
3082 if (fix_problem(ctx, problem, &pctx)) {
3083 ctx->options |= E2F_OPT_FORCE;
3084 sb->s_feature_incompat |=
3085 EXT3_FEATURE_INCOMPAT_RECOVER;
3086 ext2fs_mark_super_dirty(ctx->fs);
3087 } else if (fix_problem(ctx,
3088 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
3090 sb->s_state &= ~EXT2_VALID_FS;
3091 ext2fs_mark_super_dirty(ctx->fs);
3094 * If the user answers no to the above question, we
3095 * ignore the fact that journal apparently has data;
3096 * accidentally replaying over valid data would be far
3097 * worse than skipping a questionable recovery.
3099 * XXX should we abort with a fatal error here? What
3100 * will the ext3 kernel code do if a filesystem with
3101 * !NEEDS_RECOVERY but with a non-zero
3102 * journal->j_superblock->s_start is mounted?
3106 e2fsck_journal_release(ctx, journal, reset, 0);
3110 static errcode_t recover_ext3_journal(e2fsck_t ctx)
3115 journal_init_revoke_caches();
3116 retval = e2fsck_get_journal(ctx, &journal);
3120 retval = e2fsck_journal_load(journal);
3124 retval = journal_init_revoke(journal, 1024);
3128 retval = -journal_recover(journal);
3132 if (journal->j_superblock->s_errno) {
3133 ctx->fs->super->s_state |= EXT2_ERROR_FS;
3134 ext2fs_mark_super_dirty(ctx->fs);
3135 journal->j_superblock->s_errno = 0;
3136 mark_buffer_dirty(journal->j_sb_buffer);
3140 journal_destroy_revoke(journal);
3141 journal_destroy_revoke_caches();
3142 e2fsck_journal_release(ctx, journal, 1, 0);
3146 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
3148 io_manager io_ptr = ctx->fs->io->manager;
3149 int blocksize = ctx->fs->blocksize;
3150 errcode_t retval, recover_retval;
3152 printf(_("%s: recovering journal\n"), ctx->device_name);
3153 if (ctx->options & E2F_OPT_READONLY) {
3154 printf(_("%s: won't do journal recovery while read-only\n"),
3156 return EXT2_ET_FILE_RO;
3159 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
3160 ext2fs_flush(ctx->fs); /* Force out any modifications */
3162 recover_retval = recover_ext3_journal(ctx);
3165 * Reload the filesystem context to get up-to-date data from disk
3166 * because journal recovery will change the filesystem under us.
3168 ext2fs_close(ctx->fs);
3169 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
3170 ctx->superblock, blocksize, io_ptr,
3174 com_err(ctx->program_name, retval,
3175 _("while trying to re-open %s"),
3177 fatal_error(ctx, 0);
3179 ctx->fs->priv_data = ctx;
3181 /* Set the superblock flags */
3182 e2fsck_clear_recover(ctx, recover_retval);
3183 return recover_retval;
3187 * This function will move the journal inode from a visible file in
3188 * the filesystem directory hierarchy to the reserved inode if necessary.
3190 static const char * const journal_names[] = {
3191 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
3193 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
3195 struct ext2_super_block *sb = ctx->fs->super;
3196 struct problem_context pctx;
3197 struct ext2_inode inode;
3198 ext2_filsys fs = ctx->fs;
3201 const char * const * cpp;
3202 int group, mount_flags;
3204 clear_problem_context(&pctx);
3207 * If the filesystem is opened read-only, or there is no
3208 * journal, then do nothing.
3210 if ((ctx->options & E2F_OPT_READONLY) ||
3211 (sb->s_journal_inum == 0) ||
3212 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
3216 * Read in the journal inode
3218 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
3222 * If it's necessary to backup the journal inode, do so.
3224 if ((sb->s_jnl_backup_type == 0) ||
3225 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
3226 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
3227 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
3228 memcpy(sb->s_jnl_blocks, inode.i_block,
3230 sb->s_jnl_blocks[16] = inode.i_size;
3231 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
3232 ext2fs_mark_super_dirty(fs);
3233 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3238 * If the journal is already the hidden inode, then do nothing
3240 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
3244 * The journal inode had better have only one link and not be readable.
3246 if (inode.i_links_count != 1)
3250 * If the filesystem is mounted, or we can't tell whether
3251 * or not it's mounted, do nothing.
3253 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
3254 if (retval || (mount_flags & EXT2_MF_MOUNTED))
3258 * If we can't find the name of the journal inode, then do
3261 for (cpp = journal_names; *cpp; cpp++) {
3262 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
3263 strlen(*cpp), 0, &ino);
3264 if ((retval == 0) && (ino == sb->s_journal_inum))
3270 /* We need the inode bitmap to be loaded */
3271 retval = ext2fs_read_bitmaps(fs);
3276 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
3280 * OK, we've done all the checks, let's actually move the
3281 * journal inode. Errors at this point mean we need to force
3282 * an ext2 filesystem check.
3284 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
3286 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
3288 sb->s_journal_inum = EXT2_JOURNAL_INO;
3289 ext2fs_mark_super_dirty(fs);
3290 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3291 inode.i_links_count = 0;
3292 inode.i_dtime = time(0);
3293 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
3296 group = ext2fs_group_of_ino(fs, ino);
3297 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
3298 ext2fs_mark_ib_dirty(fs);
3299 fs->group_desc[group].bg_free_inodes_count++;
3300 fs->super->s_free_inodes_count++;
3304 pctx.errcode = retval;
3305 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
3306 fs->super->s_state &= ~EXT2_VALID_FS;
3307 ext2fs_mark_super_dirty(fs);
3312 * message.c --- print e2fsck messages (with compression)
3314 * print_e2fsck_message() prints a message to the user, using
3315 * compression techniques and expansions of abbreviations.
3317 * The following % expansions are supported:
3319 * %b <blk> block number
3320 * %B <blkcount> integer
3321 * %c <blk2> block number
3322 * %Di <dirent>->ino inode number
3323 * %Dn <dirent>->name string
3324 * %Dr <dirent>->rec_len
3325 * %Dl <dirent>->name_len
3326 * %Dt <dirent>->filetype
3327 * %d <dir> inode number
3328 * %g <group> integer
3329 * %i <ino> inode number
3330 * %Is <inode> -> i_size
3331 * %IS <inode> -> i_extra_isize
3332 * %Ib <inode> -> i_blocks
3333 * %Il <inode> -> i_links_count
3334 * %Im <inode> -> i_mode
3335 * %IM <inode> -> i_mtime
3336 * %IF <inode> -> i_faddr
3337 * %If <inode> -> i_file_acl
3338 * %Id <inode> -> i_dir_acl
3339 * %Iu <inode> -> i_uid
3340 * %Ig <inode> -> i_gid
3341 * %j <ino2> inode number
3342 * %m <com_err error message>
3344 * %p ext2fs_get_pathname of directory <ino>
3345 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
3346 * the containing directory. (If dirent is NULL
3347 * then return the pathname of directory <ino2>)
3348 * %q ext2fs_get_pathname of directory <dir>
3349 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
3350 * the containing directory.
3351 * %s <str> miscellaneous string
3352 * %S backup superblock
3353 * %X <num> hexadecimal format
3355 * The following '@' expansions are supported:
3357 * @a extended attribute
3358 * @A error allocating
3362 * @C conflicts with some other fs block
3366 * @E Entry '%Dn' in %p (%i)
3368 * @F for @i %i (%Q) is
3370 * @h HTREE directory inode
3376 * @m multiply-claimed
3390 * This structure defines the abbreviations used by the text strings
3391 * below. The first character in the string is the index letter. An
3392 * abbreviation of the form '@<i>' is expanded by looking up the index
3393 * letter <i> in the table below.
3395 static const char * const abbrevs[] = {
3396 N_("aextended attribute"),
3397 N_("Aerror allocating"),
3401 N_("Cconflicts with some other fs @b"),
3408 N_("E@e '%Dn' in %p (%i)"),
3410 N_("Ffor @i %i (%Q) is"),
3415 N_("mmultiply-claimed"),
3430 * Give more user friendly names to the "special" inodes.
3432 #define num_special_inodes 11
3433 static const char * const special_inode_name[] =
3435 N_("<The NULL inode>"), /* 0 */
3436 N_("<The bad blocks inode>"), /* 1 */
3438 N_("<The ACL index inode>"), /* 3 */
3439 N_("<The ACL data inode>"), /* 4 */
3440 N_("<The boot loader inode>"), /* 5 */
3441 N_("<The undelete directory inode>"), /* 6 */
3442 N_("<The group descriptor inode>"), /* 7 */
3443 N_("<The journal inode>"), /* 8 */
3444 N_("<Reserved inode 9>"), /* 9 */
3445 N_("<Reserved inode 10>"), /* 10 */
3449 * This function does "safe" printing. It will convert non-printable
3450 * ASCII characters using '^' and M- notation.
3452 static void safe_print(const char *cp, int len)
3462 fputs("M-", stdout);
3465 if ((ch < 32) || (ch == 0x7f)) {
3467 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
3475 * This function prints a pathname, using the ext2fs_get_pathname
3478 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
3483 if (!dir && (ino < num_special_inodes)) {
3484 fputs(_(special_inode_name[ino]), stdout);
3488 retval = ext2fs_get_pathname(fs, dir, ino, &path);
3490 fputs("???", stdout);
3492 safe_print(path, -1);
3493 ext2fs_free_mem(&path);
3497 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
3498 struct problem_context *pctx, int first);
3500 * This function handles the '@' expansion. We allow recursive
3501 * expansion; an @ expression can contain further '@' and '%'
3504 static void expand_at_expression(e2fsck_t ctx, char ch,
3505 struct problem_context *pctx,
3508 const char * const *cpp;
3511 /* Search for the abbreviation */
3512 for (cpp = abbrevs; *cpp; cpp++) {
3518 if (*first && islower(*str)) {
3520 fputc(toupper(*str++), stdout);
3522 print_e2fsck_message(ctx, str, pctx, *first);
3528 * This function expands '%IX' expressions
3530 static void expand_inode_expression(char ch,
3531 struct problem_context *ctx)
3533 struct ext2_inode *inode;
3534 struct ext2_inode_large *large_inode;
3539 if (!ctx || !ctx->inode)
3543 large_inode = (struct ext2_inode_large *) inode;
3547 if (LINUX_S_ISDIR(inode->i_mode))
3548 printf("%u", inode->i_size);
3550 #ifdef EXT2_NO_64_TYPE
3551 if (inode->i_size_high)
3552 printf("0x%x%08x", inode->i_size_high,
3555 printf("%u", inode->i_size);
3557 printf("%llu", (inode->i_size |
3558 ((__u64) inode->i_size_high << 32)));
3563 printf("%u", large_inode->i_extra_isize);
3566 printf("%u", inode->i_blocks);
3569 printf("%d", inode->i_links_count);
3572 printf("0%o", inode->i_mode);
3575 /* The diet libc doesn't respect the TZ environemnt variable */
3577 time_str = getenv("TZ");
3580 do_gmt = !strcmp(time_str, "GMT");
3583 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
3584 printf("%.24s", time_str);
3587 printf("%u", inode->i_faddr);
3590 printf("%u", inode->i_file_acl);
3593 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
3594 inode->i_dir_acl : 0));
3597 printf("%d", (inode->i_uid |
3598 (inode->osd2.linux2.l_i_uid_high << 16)));
3601 printf("%d", (inode->i_gid |
3602 (inode->osd2.linux2.l_i_gid_high << 16)));
3606 printf("%%I%c", ch);
3612 * This function expands '%dX' expressions
3614 static _INLINE_ void expand_dirent_expression(char ch,
3615 struct problem_context *ctx)
3617 struct ext2_dir_entry *dirent;
3620 if (!ctx || !ctx->dirent)
3623 dirent = ctx->dirent;
3627 printf("%u", dirent->inode);
3630 len = dirent->name_len & 0xFF;
3631 if (len > EXT2_NAME_LEN)
3632 len = EXT2_NAME_LEN;
3633 if (len > dirent->rec_len)
3634 len = dirent->rec_len;
3635 safe_print(dirent->name, len);
3638 printf("%u", dirent->rec_len);
3641 printf("%u", dirent->name_len & 0xFF);
3644 printf("%u", dirent->name_len >> 8);
3648 printf("%%D%c", ch);
3653 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
3654 struct problem_context *ctx)
3664 printf("%u", ctx->blk);
3667 #ifdef EXT2_NO_64_TYPE
3668 printf("%d", ctx->blkcount);
3670 printf("%lld", ctx->blkcount);
3674 printf("%u", ctx->blk2);
3677 printf("%u", ctx->dir);
3680 printf("%d", ctx->group);
3683 printf("%u", ctx->ino);
3686 printf("%u", ctx->ino2);
3689 printf("%s", error_message(ctx->errcode));
3692 #ifdef EXT2_NO_64_TYPE
3693 printf("%u", ctx->num);
3695 printf("%llu", ctx->num);
3699 print_pathname(fs, ctx->ino, 0);
3702 print_pathname(fs, ctx->ino2,
3703 ctx->dirent ? ctx->dirent->inode : 0);
3706 print_pathname(fs, ctx->dir, 0);
3709 print_pathname(fs, ctx->dir, ctx->ino);
3712 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
3715 printf("%s", ctx->str ? ctx->str : "NULL");
3718 #ifdef EXT2_NO_64_TYPE
3719 printf("0x%x", ctx->num);
3721 printf("0x%llx", ctx->num);
3732 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
3733 struct problem_context *pctx, int first)
3735 ext2_filsys fs = ctx->fs;
3739 e2fsck_clear_progbar(ctx);
3740 for (cp = msg; *cp; cp++) {
3743 expand_at_expression(ctx, *cp, pctx, &first);
3744 } else if (cp[0] == '%' && cp[1] == 'I') {
3746 expand_inode_expression(*cp, pctx);
3747 } else if (cp[0] == '%' && cp[1] == 'D') {
3749 expand_dirent_expression(*cp, pctx);
3750 } else if ((cp[0] == '%')) {
3752 expand_percent_expression(fs, *cp, pctx);
3754 for (i=0; cp[i]; i++)
3755 if ((cp[i] == '@') || cp[i] == '%')
3757 printf("%.*s", i, cp);
3766 * region.c --- code which manages allocations within a region.
3770 region_addr_t start;
3772 struct region_el *next;
3775 struct region_struct {
3778 struct region_el *allocated;
3781 static region_t region_create(region_addr_t min, region_addr_t max)
3785 region = malloc(sizeof(struct region_struct));
3788 memset(region, 0, sizeof(struct region_struct));
3794 static void region_free(region_t region)
3796 struct region_el *r, *next;
3798 for (r = region->allocated; r; r = next) {
3802 memset(region, 0, sizeof(struct region_struct));
3806 static int region_allocate(region_t region, region_addr_t start, int n)
3808 struct region_el *r, *new_region, *prev, *next;
3812 if ((start < region->min) || (end > region->max))
3818 * Search through the linked list. If we find that it
3819 * conflicts witih something that's already allocated, return
3820 * 1; if we can find an existing region which we can grow, do
3821 * so. Otherwise, stop when we find the appropriate place
3822 * insert a new region element into the linked list.
3824 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
3825 if (((start >= r->start) && (start < r->end)) ||
3826 ((end > r->start) && (end <= r->end)) ||
3827 ((start <= r->start) && (end >= r->end)))
3829 if (end == r->start) {
3833 if (start == r->end) {
3834 if ((next = r->next)) {
3835 if (end > next->start)
3837 if (end == next->start) {
3839 r->next = next->next;
3847 if (start < r->start)
3851 * Insert a new region element structure into the linked list
3853 new_region = malloc(sizeof(struct region_el));
3856 new_region->start = start;
3857 new_region->end = start + n;
3858 new_region->next = r;
3860 prev->next = new_region;
3862 region->allocated = new_region;
3867 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
3869 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
3870 * and applies the following tests to each inode:
3872 * - The mode field of the inode must be legal.
3873 * - The size and block count fields of the inode are correct.
3874 * - A data block must not be used by another inode
3876 * Pass 1 also gathers the collects the following information:
3878 * - A bitmap of which inodes are in use. (inode_used_map)
3879 * - A bitmap of which inodes are directories. (inode_dir_map)
3880 * - A bitmap of which inodes are regular files. (inode_reg_map)
3881 * - A bitmap of which inodes have bad fields. (inode_bad_map)
3882 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
3883 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
3884 * - A bitmap of which blocks are in use. (block_found_map)
3885 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
3886 * - The data blocks of the directory inodes. (dir_map)
3888 * Pass 1 is designed to stash away enough information so that the
3889 * other passes should not need to read in the inode information
3890 * during the normal course of a filesystem check. (Althogh if an
3891 * inconsistency is detected, other passes may need to read in an
3894 * Note that pass 1B will be invoked if there are any duplicate blocks
3899 static int process_block(ext2_filsys fs, blk_t *blocknr,
3900 e2_blkcnt_t blockcnt, blk_t ref_blk,
3901 int ref_offset, void *priv_data);
3902 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3903 e2_blkcnt_t blockcnt, blk_t ref_blk,
3904 int ref_offset, void *priv_data);
3905 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3907 static void mark_table_blocks(e2fsck_t ctx);
3908 static void alloc_bb_map(e2fsck_t ctx);
3909 static void alloc_imagic_map(e2fsck_t ctx);
3910 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3911 static void handle_fs_bad_blocks(e2fsck_t ctx);
3912 static void process_inodes(e2fsck_t ctx, char *block_buf);
3913 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
3914 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3915 dgrp_t group, void * priv_data);
3916 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3917 char *block_buf, int adjust_sign);
3918 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3920 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3921 struct ext2_inode * inode, int bufsize,
3924 struct process_block_struct_1 {
3926 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
3927 fragmented:1, compressed:1, bbcheck:1;
3930 e2_blkcnt_t last_block;
3931 int num_illegal_blocks;
3932 blk_t previous_block;
3933 struct ext2_inode *inode;
3934 struct problem_context *pctx;
3935 ext2fs_block_bitmap fs_meta_blocks;
3939 struct process_inode_block {
3941 struct ext2_inode inode;
3944 struct scan_callback_struct {
3950 * For the inodes to process list.
3952 static struct process_inode_block *inodes_to_process;
3953 static int process_inode_count;
3955 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3956 EXT2_MIN_BLOCK_LOG_SIZE + 1];
3959 * Free all memory allocated by pass1 in preparation for restarting
3962 static void unwind_pass1(void)
3964 ext2fs_free_mem(&inodes_to_process);
3968 * Check to make sure a device inode is real. Returns 1 if the device
3969 * checks out, 0 if not.
3971 * Note: this routine is now also used to check FIFO's and Sockets,
3972 * since they have the same requirement; the i_block fields should be
3976 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3981 * If i_blocks is non-zero, or the index flag is set, then
3982 * this is a bogus device/fifo/socket
3984 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3985 (inode->i_flags & EXT2_INDEX_FL))
3989 * We should be able to do the test below all the time, but
3990 * because the kernel doesn't forcibly clear the device
3991 * inode's additional i_block fields, there are some rare
3992 * occasions when a legitimate device inode will have non-zero
3993 * additional i_block fields. So for now, we only complain
3994 * when the immutable flag is set, which should never happen
3995 * for devices. (And that's when the problem is caused, since
3996 * you can't set or clear immutable flags for devices.) Once
3997 * the kernel has been fixed we can change this...
3999 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
4000 for (i=4; i < EXT2_N_BLOCKS; i++)
4001 if (inode->i_block[i])
4008 * Check to make sure a symlink inode is real. Returns 1 if the symlink
4009 * checks out, 0 if not.
4012 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
4018 if ((inode->i_size_high || inode->i_size == 0) ||
4019 (inode->i_flags & EXT2_INDEX_FL))
4022 blocks = ext2fs_inode_data_blocks(fs, inode);
4024 if ((inode->i_size >= fs->blocksize) ||
4025 (blocks != fs->blocksize >> 9) ||
4026 (inode->i_block[0] < fs->super->s_first_data_block) ||
4027 (inode->i_block[0] >= fs->super->s_blocks_count))
4030 for (i = 1; i < EXT2_N_BLOCKS; i++)
4031 if (inode->i_block[i])
4034 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
4037 len = strnlen(buf, fs->blocksize);
4038 if (len == fs->blocksize)
4041 if (inode->i_size >= sizeof(inode->i_block))
4044 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
4045 if (len == sizeof(inode->i_block))
4048 if (len != inode->i_size)
4054 * If the immutable (or append-only) flag is set on the inode, offer
4057 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
4058 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
4060 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
4063 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
4066 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
4067 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4071 * If device, fifo or socket, check size is zero -- if not offer to
4074 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
4076 struct ext2_inode *inode = pctx->inode;
4078 if ((inode->i_size == 0) && (inode->i_size_high == 0))
4081 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
4085 inode->i_size_high = 0;
4086 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4089 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
4091 struct ext2_super_block *sb = ctx->fs->super;
4092 struct ext2_inode_large *inode;
4093 struct ext2_ext_attr_entry *entry;
4095 int storage_size, remain, offs;
4098 inode = (struct ext2_inode_large *) pctx->inode;
4099 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
4100 inode->i_extra_isize;
4101 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4102 inode->i_extra_isize + sizeof(__u32);
4103 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
4104 entry = (struct ext2_ext_attr_entry *) start;
4106 /* scan all entry's headers first */
4108 /* take finish entry 0UL into account */
4109 remain = storage_size - sizeof(__u32);
4112 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
4114 /* header eats this space */
4115 remain -= sizeof(struct ext2_ext_attr_entry);
4117 /* is attribute name valid? */
4118 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
4119 pctx->num = entry->e_name_len;
4120 problem = PR_1_ATTR_NAME_LEN;
4124 /* attribute len eats this space */
4125 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
4127 /* check value size */
4128 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
4129 pctx->num = entry->e_value_size;
4130 problem = PR_1_ATTR_VALUE_SIZE;
4134 /* check value placement */
4135 if (entry->e_value_offs +
4136 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
4137 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
4138 pctx->num = entry->e_value_offs;
4139 problem = PR_1_ATTR_VALUE_OFFSET;
4143 /* e_value_block must be 0 in inode's ea */
4144 if (entry->e_value_block != 0) {
4145 pctx->num = entry->e_value_block;
4146 problem = PR_1_ATTR_VALUE_BLOCK;
4150 /* e_hash must be 0 in inode's ea */
4151 if (entry->e_hash != 0) {
4152 pctx->num = entry->e_hash;
4153 problem = PR_1_ATTR_HASH;
4157 remain -= entry->e_value_size;
4158 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
4160 entry = EXT2_EXT_ATTR_NEXT(entry);
4164 * it seems like a corruption. it's very unlikely we could repair
4165 * EA(s) in automatic fashion -bzzz
4168 problem = PR_1_ATTR_HASH;
4170 if (problem == 0 || !fix_problem(ctx, problem, pctx))
4173 /* simple remove all possible EA(s) */
4174 *((__u32 *)start) = 0UL;
4175 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
4176 EXT2_INODE_SIZE(sb), "pass1");
4179 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
4181 struct ext2_super_block *sb = ctx->fs->super;
4182 struct ext2_inode_large *inode;
4186 inode = (struct ext2_inode_large *) pctx->inode;
4187 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
4188 /* this isn't large inode. so, nothing to check */
4193 printf("inode #%u, i_extra_size %d\n", pctx->ino,
4194 inode->i_extra_isize);
4196 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
4197 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
4198 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
4200 * For now we will allow i_extra_isize to be 0, but really
4201 * implementations should never allow i_extra_isize to be 0
4203 if (inode->i_extra_isize &&
4204 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
4205 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
4207 inode->i_extra_isize = min;
4208 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
4209 EXT2_INODE_SIZE(sb), "pass1");
4213 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4214 inode->i_extra_isize);
4215 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
4216 /* it seems inode has an extended attribute(s) in body */
4217 check_ea_in_inode(ctx, pctx);
4221 static void e2fsck_pass1(e2fsck_t ctx)
4225 ext2_filsys fs = ctx->fs;
4227 struct ext2_inode *inode;
4228 ext2_inode_scan scan;
4230 #ifdef RESOURCE_TRACK
4231 struct resource_track rtrack;
4233 unsigned char frag, fsize;
4234 struct problem_context pctx;
4235 struct scan_callback_struct scan_struct;
4236 struct ext2_super_block *sb = ctx->fs->super;
4238 int busted_fs_time = 0;
4241 #ifdef RESOURCE_TRACK
4242 init_resource_track(&rtrack);
4244 clear_problem_context(&pctx);
4246 if (!(ctx->options & E2F_OPT_PREEN))
4247 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
4249 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4250 !(ctx->options & E2F_OPT_NO)) {
4251 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
4252 ctx->dirs_to_hash = 0;
4256 mtrace_print("Pass 1");
4259 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
4261 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
4262 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
4263 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
4264 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
4265 max_sizes = (max_sizes * (1UL << i)) - 1;
4266 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
4270 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
4273 * Allocate bitmaps structures
4275 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
4276 &ctx->inode_used_map);
4279 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4280 ctx->flags |= E2F_FLAG_ABORT;
4283 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4284 _("directory inode map"), &ctx->inode_dir_map);
4287 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4288 ctx->flags |= E2F_FLAG_ABORT;
4291 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4292 _("regular file inode map"), &ctx->inode_reg_map);
4295 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4296 ctx->flags |= E2F_FLAG_ABORT;
4299 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
4300 &ctx->block_found_map);
4303 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4304 ctx->flags |= E2F_FLAG_ABORT;
4307 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
4308 &ctx->inode_link_info);
4310 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
4311 ctx->flags |= E2F_FLAG_ABORT;
4314 inode_size = EXT2_INODE_SIZE(fs->super);
4315 inode = (struct ext2_inode *)
4316 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
4318 inodes_to_process = (struct process_inode_block *)
4319 e2fsck_allocate_memory(ctx,
4320 (ctx->process_inode_size *
4321 sizeof(struct process_inode_block)),
4322 "array of inodes to process");
4323 process_inode_count = 0;
4325 pctx.errcode = ext2fs_init_dblist(fs, 0);
4327 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
4328 ctx->flags |= E2F_FLAG_ABORT;
4333 * If the last orphan field is set, clear it, since the pass1
4334 * processing will automatically find and clear the orphans.
4335 * In the future, we may want to try using the last_orphan
4336 * linked list ourselves, but for now, we clear it so that the
4337 * ext3 mount code won't get confused.
4339 if (!(ctx->options & E2F_OPT_READONLY)) {
4340 if (fs->super->s_last_orphan) {
4341 fs->super->s_last_orphan = 0;
4342 ext2fs_mark_super_dirty(fs);
4346 mark_table_blocks(ctx);
4347 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
4348 "block interate buffer");
4349 e2fsck_use_inode_shortcuts(ctx, 1);
4350 ehandler_operation(_("doing inode scan"));
4351 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4354 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4355 ctx->flags |= E2F_FLAG_ABORT;
4358 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
4359 ctx->stashed_inode = inode;
4360 scan_struct.ctx = ctx;
4361 scan_struct.block_buf = block_buf;
4362 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
4364 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
4366 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
4367 (fs->super->s_mtime < fs->super->s_inodes_count))
4371 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
4373 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4375 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
4376 if (!ctx->inode_bb_map)
4378 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
4379 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4383 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4384 ctx->flags |= E2F_FLAG_ABORT;
4391 ctx->stashed_ino = ino;
4392 if (inode->i_links_count) {
4393 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
4394 ino, inode->i_links_count);
4396 pctx.num = inode->i_links_count;
4397 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
4398 ctx->flags |= E2F_FLAG_ABORT;
4402 if (ino == EXT2_BAD_INO) {
4403 struct process_block_struct_1 pb;
4405 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
4406 &pb.fs_meta_blocks);
4409 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4410 ctx->flags |= E2F_FLAG_ABORT;
4413 pb.ino = EXT2_BAD_INO;
4414 pb.num_blocks = pb.last_block = 0;
4415 pb.num_illegal_blocks = 0;
4416 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
4417 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
4421 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
4422 block_buf, process_bad_block, &pb);
4423 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
4425 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
4426 ctx->flags |= E2F_FLAG_ABORT;
4430 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
4431 ctx->flags |= E2F_FLAG_ABORT;
4434 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4435 clear_problem_context(&pctx);
4437 } else if (ino == EXT2_ROOT_INO) {
4439 * Make sure the root inode is a directory; if
4440 * not, offer to clear it. It will be
4441 * regnerated in pass #3.
4443 if (!LINUX_S_ISDIR(inode->i_mode)) {
4444 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
4445 inode->i_dtime = time(0);
4446 inode->i_links_count = 0;
4447 ext2fs_icount_store(ctx->inode_link_info,
4449 e2fsck_write_inode(ctx, ino, inode,
4455 * If dtime is set, offer to clear it. mke2fs
4456 * version 0.2b created filesystems with the
4457 * dtime field set for the root and lost+found
4458 * directories. We won't worry about
4459 * /lost+found, since that can be regenerated
4460 * easily. But we will fix the root directory
4461 * as a special case.
4463 if (inode->i_dtime && inode->i_links_count) {
4464 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
4466 e2fsck_write_inode(ctx, ino, inode,
4470 } else if (ino == EXT2_JOURNAL_INO) {
4471 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4472 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
4473 if (!LINUX_S_ISREG(inode->i_mode) &&
4474 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
4476 inode->i_mode = LINUX_S_IFREG;
4477 e2fsck_write_inode(ctx, ino, inode,
4480 check_blocks(ctx, &pctx, block_buf);
4483 if ((inode->i_links_count || inode->i_blocks ||
4484 inode->i_blocks || inode->i_block[0]) &&
4485 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
4487 memset(inode, 0, inode_size);
4488 ext2fs_icount_store(ctx->inode_link_info,
4490 e2fsck_write_inode_full(ctx, ino, inode,
4491 inode_size, "pass1");
4493 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
4496 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4497 if (ino == EXT2_BOOT_LOADER_INO) {
4498 if (LINUX_S_ISDIR(inode->i_mode))
4499 problem = PR_1_RESERVED_BAD_MODE;
4500 } else if (ino == EXT2_RESIZE_INO) {
4501 if (inode->i_mode &&
4502 !LINUX_S_ISREG(inode->i_mode))
4503 problem = PR_1_RESERVED_BAD_MODE;
4505 if (inode->i_mode != 0)
4506 problem = PR_1_RESERVED_BAD_MODE;
4509 if (fix_problem(ctx, problem, &pctx)) {
4511 e2fsck_write_inode(ctx, ino, inode,
4515 check_blocks(ctx, &pctx, block_buf);
4519 * Check for inodes who might have been part of the
4520 * orphaned list linked list. They should have gotten
4521 * dealt with by now, unless the list had somehow been
4524 * FIXME: In the future, inodes which are still in use
4525 * (and which are therefore) pending truncation should
4526 * be handled specially. Right now we just clear the
4527 * dtime field, and the normal e2fsck handling of
4528 * inodes where i_size and the inode blocks are
4529 * inconsistent is to fix i_size, instead of releasing
4530 * the extra blocks. This won't catch the inodes that
4531 * was at the end of the orphan list, but it's better
4532 * than nothing. The right answer is that there
4533 * shouldn't be any bugs in the orphan list handling. :-)
4535 if (inode->i_dtime && !busted_fs_time &&
4536 inode->i_dtime < ctx->fs->super->s_inodes_count) {
4537 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
4538 inode->i_dtime = inode->i_links_count ?
4540 e2fsck_write_inode(ctx, ino, inode,
4546 * This code assumes that deleted inodes have
4547 * i_links_count set to 0.
4549 if (!inode->i_links_count) {
4550 if (!inode->i_dtime && inode->i_mode) {
4551 if (fix_problem(ctx,
4552 PR_1_ZERO_DTIME, &pctx)) {
4553 inode->i_dtime = time(0);
4554 e2fsck_write_inode(ctx, ino, inode,
4561 * n.b. 0.3c ext2fs code didn't clear i_links_count for
4562 * deleted files. Oops.
4564 * Since all new ext2 implementations get this right,
4565 * we now assume that the case of non-zero
4566 * i_links_count and non-zero dtime means that we
4567 * should keep the file, not delete it.
4570 if (inode->i_dtime) {
4571 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
4573 e2fsck_write_inode(ctx, ino, inode, "pass1");
4577 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4578 switch (fs->super->s_creator_os) {
4580 frag = inode->osd2.linux2.l_i_frag;
4581 fsize = inode->osd2.linux2.l_i_fsize;
4584 frag = inode->osd2.hurd2.h_i_frag;
4585 fsize = inode->osd2.hurd2.h_i_fsize;
4588 frag = inode->osd2.masix2.m_i_frag;
4589 fsize = inode->osd2.masix2.m_i_fsize;
4595 if (inode->i_faddr || frag || fsize ||
4596 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
4597 mark_inode_bad(ctx, ino);
4598 if (inode->i_flags & EXT2_IMAGIC_FL) {
4600 if (!ctx->inode_imagic_map)
4601 alloc_imagic_map(ctx);
4602 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
4605 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
4606 inode->i_flags &= ~EXT2_IMAGIC_FL;
4607 e2fsck_write_inode(ctx, ino,
4613 check_inode_extra_space(ctx, &pctx);
4615 if (LINUX_S_ISDIR(inode->i_mode)) {
4616 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
4617 e2fsck_add_dir_info(ctx, ino, 0);
4618 ctx->fs_directory_count++;
4619 } else if (LINUX_S_ISREG (inode->i_mode)) {
4620 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
4621 ctx->fs_regular_count++;
4622 } else if (LINUX_S_ISCHR (inode->i_mode) &&
4623 e2fsck_pass1_check_device_inode(fs, inode)) {
4624 check_immutable(ctx, &pctx);
4625 check_size(ctx, &pctx);
4626 ctx->fs_chardev_count++;
4627 } else if (LINUX_S_ISBLK (inode->i_mode) &&
4628 e2fsck_pass1_check_device_inode(fs, inode)) {
4629 check_immutable(ctx, &pctx);
4630 check_size(ctx, &pctx);
4631 ctx->fs_blockdev_count++;
4632 } else if (LINUX_S_ISLNK (inode->i_mode) &&
4633 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
4634 check_immutable(ctx, &pctx);
4635 ctx->fs_symlinks_count++;
4636 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
4637 ctx->fs_fast_symlinks_count++;
4638 check_blocks(ctx, &pctx, block_buf);
4642 else if (LINUX_S_ISFIFO (inode->i_mode) &&
4643 e2fsck_pass1_check_device_inode(fs, inode)) {
4644 check_immutable(ctx, &pctx);
4645 check_size(ctx, &pctx);
4646 ctx->fs_fifo_count++;
4647 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
4648 e2fsck_pass1_check_device_inode(fs, inode)) {
4649 check_immutable(ctx, &pctx);
4650 check_size(ctx, &pctx);
4651 ctx->fs_sockets_count++;
4653 mark_inode_bad(ctx, ino);
4654 if (inode->i_block[EXT2_IND_BLOCK])
4655 ctx->fs_ind_count++;
4656 if (inode->i_block[EXT2_DIND_BLOCK])
4657 ctx->fs_dind_count++;
4658 if (inode->i_block[EXT2_TIND_BLOCK])
4659 ctx->fs_tind_count++;
4660 if (inode->i_block[EXT2_IND_BLOCK] ||
4661 inode->i_block[EXT2_DIND_BLOCK] ||
4662 inode->i_block[EXT2_TIND_BLOCK] ||
4663 inode->i_file_acl) {
4664 inodes_to_process[process_inode_count].ino = ino;
4665 inodes_to_process[process_inode_count].inode = *inode;
4666 process_inode_count++;
4668 check_blocks(ctx, &pctx, block_buf);
4670 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4673 if (process_inode_count >= ctx->process_inode_size) {
4674 process_inodes(ctx, block_buf);
4676 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4680 process_inodes(ctx, block_buf);
4681 ext2fs_close_inode_scan(scan);
4682 ehandler_operation(0);
4685 * If any extended attribute blocks' reference counts need to
4686 * be adjusted, either up (ctx->refcount_extra), or down
4687 * (ctx->refcount), then fix them.
4689 if (ctx->refcount) {
4690 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
4691 ea_refcount_free(ctx->refcount);
4694 if (ctx->refcount_extra) {
4695 adjust_extattr_refcount(ctx, ctx->refcount_extra,
4697 ea_refcount_free(ctx->refcount_extra);
4698 ctx->refcount_extra = 0;
4701 if (ctx->invalid_bitmaps)
4702 handle_fs_bad_blocks(ctx);
4704 /* We don't need the block_ea_map any more */
4705 ext2fs_free_block_bitmap(ctx->block_ea_map);
4706 ctx->block_ea_map = 0;
4708 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
4709 ext2fs_block_bitmap save_bmap;
4711 save_bmap = fs->block_map;
4712 fs->block_map = ctx->block_found_map;
4713 clear_problem_context(&pctx);
4714 pctx.errcode = ext2fs_create_resize_inode(fs);
4716 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
4717 /* Should never get here */
4718 ctx->flags |= E2F_FLAG_ABORT;
4721 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
4723 inode->i_mtime = time(0);
4724 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
4726 fs->block_map = save_bmap;
4727 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
4730 if (ctx->flags & E2F_FLAG_RESTART) {
4732 * Only the master copy of the superblock and block
4733 * group descriptors are going to be written during a
4734 * restart, so set the superblock to be used to be the
4735 * master superblock.
4737 ctx->use_superblock = 0;
4742 if (ctx->block_dup_map) {
4743 if (ctx->options & E2F_OPT_PREEN) {
4744 clear_problem_context(&pctx);
4745 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
4747 e2fsck_pass1_dupblocks(ctx, block_buf);
4749 ext2fs_free_mem(&inodes_to_process);
4751 e2fsck_use_inode_shortcuts(ctx, 0);
4753 ext2fs_free_mem(&block_buf);
4754 ext2fs_free_mem(&inode);
4756 #ifdef RESOURCE_TRACK
4757 if (ctx->options & E2F_OPT_TIME2) {
4758 e2fsck_clear_progbar(ctx);
4759 print_resource_track(_("Pass 1"), &rtrack);
4765 * When the inode_scan routines call this callback at the end of the
4766 * glock group, call process_inodes.
4768 static errcode_t scan_callback(ext2_filsys fs,
4769 ext2_inode_scan scan FSCK_ATTR((unused)),
4770 dgrp_t group, void * priv_data)
4772 struct scan_callback_struct *scan_struct;
4775 scan_struct = (struct scan_callback_struct *) priv_data;
4776 ctx = scan_struct->ctx;
4778 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
4781 if ((ctx->progress)(ctx, 1, group+1,
4782 ctx->fs->group_desc_count))
4783 return EXT2_ET_CANCEL_REQUESTED;
4789 * Process the inodes in the "inodes to process" list.
4791 static void process_inodes(e2fsck_t ctx, char *block_buf)
4794 struct ext2_inode *old_stashed_inode;
4795 ext2_ino_t old_stashed_ino;
4796 const char *old_operation;
4798 struct problem_context pctx;
4801 printf("begin process_inodes: ");
4803 if (process_inode_count == 0)
4805 old_operation = ehandler_operation(0);
4806 old_stashed_inode = ctx->stashed_inode;
4807 old_stashed_ino = ctx->stashed_ino;
4808 qsort(inodes_to_process, process_inode_count,
4809 sizeof(struct process_inode_block), process_inode_cmp);
4810 clear_problem_context(&pctx);
4811 for (i=0; i < process_inode_count; i++) {
4812 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
4813 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
4816 printf("%u ", pctx.ino);
4818 sprintf(buf, _("reading indirect blocks of inode %u"),
4820 ehandler_operation(buf);
4821 check_blocks(ctx, &pctx, block_buf);
4822 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4825 ctx->stashed_inode = old_stashed_inode;
4826 ctx->stashed_ino = old_stashed_ino;
4827 process_inode_count = 0;
4829 printf("end process inodes\n");
4831 ehandler_operation(old_operation);
4834 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
4836 const struct process_inode_block *ib_a =
4837 (const struct process_inode_block *) a;
4838 const struct process_inode_block *ib_b =
4839 (const struct process_inode_block *) b;
4842 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
4843 ib_b->inode.i_block[EXT2_IND_BLOCK]);
4845 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
4850 * Mark an inode as being bad in some what
4852 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
4854 struct problem_context pctx;
4856 if (!ctx->inode_bad_map) {
4857 clear_problem_context(&pctx);
4859 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4860 _("bad inode map"), &ctx->inode_bad_map);
4863 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4864 /* Should never get here */
4865 ctx->flags |= E2F_FLAG_ABORT;
4869 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
4874 * This procedure will allocate the inode "bb" (badblock) map table
4876 static void alloc_bb_map(e2fsck_t ctx)
4878 struct problem_context pctx;
4880 clear_problem_context(&pctx);
4881 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4882 _("inode in bad block map"),
4883 &ctx->inode_bb_map);
4886 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4887 /* Should never get here */
4888 ctx->flags |= E2F_FLAG_ABORT;
4894 * This procedure will allocate the inode imagic table
4896 static void alloc_imagic_map(e2fsck_t ctx)
4898 struct problem_context pctx;
4900 clear_problem_context(&pctx);
4901 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4902 _("imagic inode map"),
4903 &ctx->inode_imagic_map);
4906 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4907 /* Should never get here */
4908 ctx->flags |= E2F_FLAG_ABORT;
4914 * Marks a block as in use, setting the dup_map if it's been set
4915 * already. Called by process_block and process_bad_block.
4917 * WARNING: Assumes checks have already been done to make sure block
4918 * is valid. This is true in both process_block and process_bad_block.
4920 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
4922 struct problem_context pctx;
4924 clear_problem_context(&pctx);
4926 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4927 if (!ctx->block_dup_map) {
4928 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4929 _("multiply claimed block map"),
4930 &ctx->block_dup_map);
4933 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4935 /* Should never get here */
4936 ctx->flags |= E2F_FLAG_ABORT;
4940 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4942 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4947 * Adjust the extended attribute block's reference counts at the end
4948 * of pass 1, either by subtracting out references for EA blocks that
4949 * are still referenced in ctx->refcount, or by adding references for
4950 * EA blocks that had extra references as accounted for in
4951 * ctx->refcount_extra.
4953 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4954 char *block_buf, int adjust_sign)
4956 struct ext2_ext_attr_header *header;
4957 struct problem_context pctx;
4958 ext2_filsys fs = ctx->fs;
4963 clear_problem_context(&pctx);
4965 ea_refcount_intr_begin(refcount);
4967 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4970 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4972 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4975 header = (struct ext2_ext_attr_header *) block_buf;
4976 pctx.blkcount = header->h_refcount;
4977 should_be = header->h_refcount + adjust_sign * count;
4978 pctx.num = should_be;
4979 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4980 header->h_refcount = should_be;
4981 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4984 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4992 * Handle processing the extended attribute blocks
4994 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4997 ext2_filsys fs = ctx->fs;
4998 ext2_ino_t ino = pctx->ino;
4999 struct ext2_inode *inode = pctx->inode;
5002 struct ext2_ext_attr_header *header;
5003 struct ext2_ext_attr_entry *entry;
5007 blk = inode->i_file_acl;
5012 * If the Extended attribute flag isn't set, then a non-zero
5013 * file acl means that the inode is corrupted.
5015 * Or if the extended attribute block is an invalid block,
5016 * then the inode is also corrupted.
5018 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
5019 (blk < fs->super->s_first_data_block) ||
5020 (blk >= fs->super->s_blocks_count)) {
5021 mark_inode_bad(ctx, ino);
5025 /* If ea bitmap hasn't been allocated, create it */
5026 if (!ctx->block_ea_map) {
5027 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
5028 _("ext attr block map"),
5029 &ctx->block_ea_map);
5030 if (pctx->errcode) {
5032 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
5033 ctx->flags |= E2F_FLAG_ABORT;
5038 /* Create the EA refcount structure if necessary */
5039 if (!ctx->refcount) {
5040 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
5041 if (pctx->errcode) {
5043 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5044 ctx->flags |= E2F_FLAG_ABORT;
5050 /* Debugging text */
5051 printf("Inode %u has EA block %u\n", ino, blk);
5054 /* Have we seen this EA block before? */
5055 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
5056 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
5058 /* Ooops, this EA was referenced more than it stated */
5059 if (!ctx->refcount_extra) {
5060 pctx->errcode = ea_refcount_create(0,
5061 &ctx->refcount_extra);
5062 if (pctx->errcode) {
5064 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5065 ctx->flags |= E2F_FLAG_ABORT;
5069 ea_refcount_increment(ctx->refcount_extra, blk, 0);
5074 * OK, we haven't seen this EA block yet. So we need to
5078 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5079 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
5081 header = (struct ext2_ext_attr_header *) block_buf;
5082 pctx->blk = inode->i_file_acl;
5083 if (((ctx->ext_attr_ver == 1) &&
5084 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
5085 ((ctx->ext_attr_ver == 2) &&
5086 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
5087 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
5091 if (header->h_blocks != 1) {
5092 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
5096 region = region_create(0, fs->blocksize);
5098 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
5099 ctx->flags |= E2F_FLAG_ABORT;
5102 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
5103 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5107 entry = (struct ext2_ext_attr_entry *)(header+1);
5108 end = block_buf + fs->blocksize;
5109 while ((char *)entry < end && *(__u32 *)entry) {
5110 if (region_allocate(region, (char *)entry - (char *)header,
5111 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
5112 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5115 if ((ctx->ext_attr_ver == 1 &&
5116 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
5117 (ctx->ext_attr_ver == 2 &&
5118 entry->e_name_index == 0)) {
5119 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
5122 if (entry->e_value_block != 0) {
5123 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
5126 if (entry->e_value_size &&
5127 region_allocate(region, entry->e_value_offs,
5128 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
5129 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5132 entry = EXT2_EXT_ATTR_NEXT(entry);
5134 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
5135 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5138 region_free(region);
5140 count = header->h_refcount - 1;
5142 ea_refcount_store(ctx->refcount, blk, count);
5143 mark_block_used(ctx, blk);
5144 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
5149 inode->i_file_acl = 0;
5150 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
5154 /* Returns 1 if bad htree, 0 if OK */
5155 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
5156 ext2_ino_t ino FSCK_ATTR((unused)),
5157 struct ext2_inode *inode,
5160 struct ext2_dx_root_info *root;
5161 ext2_filsys fs = ctx->fs;
5165 if ((!LINUX_S_ISDIR(inode->i_mode) &&
5166 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
5167 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
5168 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
5171 blk = inode->i_block[0];
5173 (blk < fs->super->s_first_data_block) ||
5174 (blk >= fs->super->s_blocks_count)) &&
5175 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5178 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
5179 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5182 /* XXX should check that beginning matches a directory */
5183 root = (struct ext2_dx_root_info *) (block_buf + 24);
5185 if ((root->reserved_zero || root->info_length < 8) &&
5186 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5189 pctx->num = root->hash_version;
5190 if ((root->hash_version != EXT2_HASH_LEGACY) &&
5191 (root->hash_version != EXT2_HASH_HALF_MD4) &&
5192 (root->hash_version != EXT2_HASH_TEA) &&
5193 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
5196 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
5197 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
5200 pctx->num = root->indirect_levels;
5201 if ((root->indirect_levels > 1) &&
5202 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
5209 * This subroutine is called on each inode to account for all of the
5210 * blocks used by that inode.
5212 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
5215 ext2_filsys fs = ctx->fs;
5216 struct process_block_struct_1 pb;
5217 ext2_ino_t ino = pctx->ino;
5218 struct ext2_inode *inode = pctx->inode;
5220 int dirty_inode = 0;
5226 pb.num_illegal_blocks = 0;
5227 pb.suppress = 0; pb.clear = 0;
5230 pb.previous_block = 0;
5231 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
5232 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
5233 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
5240 if (inode->i_flags & EXT2_COMPRBLK_FL) {
5241 if (fs->super->s_feature_incompat &
5242 EXT2_FEATURE_INCOMPAT_COMPRESSION)
5245 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
5246 inode->i_flags &= ~EXT2_COMPRBLK_FL;
5252 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
5255 if (ext2fs_inode_has_valid_blocks(inode))
5256 pctx->errcode = ext2fs_block_iterate2(fs, ino,
5257 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
5258 block_buf, process_block, &pb);
5259 end_problem_latch(ctx, PR_LATCH_BLOCK);
5260 end_problem_latch(ctx, PR_LATCH_TOOBIG);
5261 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5264 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
5266 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
5267 ctx->fs_fragmented++;
5270 inode->i_links_count = 0;
5271 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5272 inode->i_dtime = time(0);
5274 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5275 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5276 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5278 * The inode was probably partially accounted for
5279 * before processing was aborted, so we need to
5280 * restart the pass 1 scan.
5282 ctx->flags |= E2F_FLAG_RESTART;
5286 if (inode->i_flags & EXT2_INDEX_FL) {
5287 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
5288 inode->i_flags &= ~EXT2_INDEX_FL;
5292 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
5296 if (ctx->dirs_to_hash && pb.is_dir &&
5297 !(inode->i_flags & EXT2_INDEX_FL) &&
5298 ((inode->i_size / fs->blocksize) >= 3))
5299 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
5301 if (!pb.num_blocks && pb.is_dir) {
5302 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
5303 inode->i_links_count = 0;
5304 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5305 inode->i_dtime = time(0);
5307 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5308 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5309 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5310 ctx->fs_directory_count--;
5315 pb.num_blocks *= (fs->blocksize / 512);
5317 printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
5318 ino, inode->i_size, pb.last_block, inode->i_blocks,
5322 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
5323 if (nblock > (pb.last_block + 1))
5325 else if (nblock < (pb.last_block + 1)) {
5326 if (((pb.last_block + 1) - nblock) >
5327 fs->super->s_prealloc_dir_blocks)
5331 size = EXT2_I_SIZE(inode);
5332 if ((pb.last_block >= 0) &&
5333 (size < (__u64) pb.last_block * fs->blocksize))
5335 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
5338 /* i_size for symlinks is checked elsewhere */
5339 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
5340 pctx->num = (pb.last_block+1) * fs->blocksize;
5341 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
5342 inode->i_size = pctx->num;
5343 if (!LINUX_S_ISDIR(inode->i_mode))
5344 inode->i_size_high = pctx->num >> 32;
5349 if (LINUX_S_ISREG(inode->i_mode) &&
5350 (inode->i_size_high || inode->i_size & 0x80000000UL))
5352 if (pb.num_blocks != inode->i_blocks) {
5353 pctx->num = pb.num_blocks;
5354 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
5355 inode->i_blocks = pb.num_blocks;
5362 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
5367 * Helper function called by process block when an illegal block is
5368 * found. It returns a description about why the block is illegal
5370 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
5374 static char problem[80];
5376 super = fs->super->s_first_data_block;
5377 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
5378 if (block < super) {
5379 sprintf(problem, "< FIRSTBLOCK (%u)", super);
5381 } else if (block >= fs->super->s_blocks_count) {
5382 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
5385 for (i = 0; i < fs->group_desc_count; i++) {
5386 if (block == super) {
5387 sprintf(problem, "is the superblock in group %d", i);
5390 if (block > super &&
5391 block <= (super + fs->desc_blocks)) {
5392 sprintf(problem, "is in the group descriptors "
5396 if (block == fs->group_desc[i].bg_block_bitmap) {
5397 sprintf(problem, "is the block bitmap of group %d", i);
5400 if (block == fs->group_desc[i].bg_inode_bitmap) {
5401 sprintf(problem, "is the inode bitmap of group %d", i);
5404 if (block >= fs->group_desc[i].bg_inode_table &&
5405 (block < fs->group_desc[i].bg_inode_table
5406 + fs->inode_blocks_per_group)) {
5407 sprintf(problem, "is in the inode table of group %d",
5411 super += fs->super->s_blocks_per_group;
5418 * This is a helper function for check_blocks().
5420 static int process_block(ext2_filsys fs,
5422 e2_blkcnt_t blockcnt,
5423 blk_t ref_block FSCK_ATTR((unused)),
5424 int ref_offset FSCK_ATTR((unused)),
5427 struct process_block_struct_1 *p;
5428 struct problem_context *pctx;
5429 blk_t blk = *block_nr;
5434 p = (struct process_block_struct_1 *) priv_data;
5438 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
5439 /* todo: Check that the comprblk_fl is high, that the
5440 blkaddr pattern looks right (all non-holes up to
5441 first EXT2FS_COMPRESSED_BLKADDR, then all
5442 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
5443 that the feature_incompat bit is high, and that the
5444 inode is a regular file. If we're doing a "full
5445 check" (a concept introduced to e2fsck by e2compr,
5446 meaning that we look at data blocks as well as
5447 metadata) then call some library routine that
5448 checks the compressed data. I'll have to think
5449 about this, because one particularly important
5450 problem to be able to fix is to recalculate the
5451 cluster size if necessary. I think that perhaps
5452 we'd better do most/all e2compr-specific checks
5453 separately, after the non-e2compr checks. If not
5454 doing a full check, it may be useful to test that
5455 the personality is linux; e.g. if it isn't then
5456 perhaps this really is just an illegal block. */
5461 if (p->is_dir == 0) {
5463 * Should never happen, since only directories
5464 * get called with BLOCK_FLAG_HOLE
5467 printf("process_block() called with blk == 0, "
5468 "blockcnt=%d, inode %lu???\n",
5475 if (blockcnt * fs->blocksize < p->inode->i_size) {
5477 printf("Missing block (#%d) in directory inode %lu!\n",
5486 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
5491 * Simplistic fragmentation check. We merely require that the
5492 * file be contiguous. (Which can never be true for really
5493 * big files that are greater than a block group.)
5495 if (!HOLE_BLKADDR(p->previous_block)) {
5496 if (p->previous_block+1 != blk)
5499 p->previous_block = blk;
5501 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
5502 problem = PR_1_TOOBIG_DIR;
5503 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
5504 problem = PR_1_TOOBIG_REG;
5505 if (!p->is_dir && !p->is_reg && blockcnt > 0)
5506 problem = PR_1_TOOBIG_SYMLINK;
5508 if (blk < fs->super->s_first_data_block ||
5509 blk >= fs->super->s_blocks_count)
5510 problem = PR_1_ILLEGAL_BLOCK_NUM;
5513 p->num_illegal_blocks++;
5514 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
5515 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
5519 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
5521 set_latch_flags(PR_LATCH_BLOCK,
5526 pctx->blkcount = blockcnt;
5527 if (fix_problem(ctx, problem, pctx)) {
5528 blk = *block_nr = 0;
5529 ret_code = BLOCK_CHANGED;
5535 if (p->ino == EXT2_RESIZE_INO) {
5537 * The resize inode has already be sanity checked
5538 * during pass #0 (the superblock checks). All we
5539 * have to do is mark the double indirect block as
5540 * being in use; all of the other blocks are handled
5541 * by mark_table_blocks()).
5543 if (blockcnt == BLOCK_COUNT_DIND)
5544 mark_block_used(ctx, blk);
5546 mark_block_used(ctx, blk);
5549 p->last_block = blockcnt;
5551 if (p->is_dir && (blockcnt >= 0)) {
5552 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
5554 if (pctx->errcode) {
5556 pctx->num = blockcnt;
5557 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
5558 /* Should never get here */
5559 ctx->flags |= E2F_FLAG_ABORT;
5566 static int process_bad_block(ext2_filsys fs,
5568 e2_blkcnt_t blockcnt,
5569 blk_t ref_block FSCK_ATTR((unused)),
5570 int ref_offset FSCK_ATTR((unused)),
5573 struct process_block_struct_1 *p;
5574 blk_t blk = *block_nr;
5577 struct problem_context *pctx;
5581 * Note: This function processes blocks for the bad blocks
5582 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
5588 p = (struct process_block_struct_1 *) priv_data;
5592 pctx->ino = EXT2_BAD_INO;
5594 pctx->blkcount = blockcnt;
5596 if ((blk < fs->super->s_first_data_block) ||
5597 (blk >= fs->super->s_blocks_count)) {
5598 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
5600 return BLOCK_CHANGED;
5606 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
5608 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
5610 return BLOCK_CHANGED;
5612 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
5615 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
5618 return BLOCK_CHANGED;
5620 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5623 mark_block_used(ctx, blk);
5627 printf ("DEBUG: Marking %u as bad.\n", blk);
5629 ctx->fs_badblocks_count++;
5631 * If the block is not used, then mark it as used and return.
5632 * If it is already marked as found, this must mean that
5633 * there's an overlap between the filesystem table blocks
5634 * (bitmaps and inode table) and the bad block list.
5636 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
5637 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
5641 * Try to find the where the filesystem block was used...
5643 first_block = fs->super->s_first_data_block;
5645 for (i = 0; i < fs->group_desc_count; i++ ) {
5648 if (!ext2fs_bg_has_super(fs, i))
5650 if (blk == first_block) {
5652 if (fix_problem(ctx,
5653 PR_1_BAD_PRIMARY_SUPERBLOCK,
5656 return BLOCK_CHANGED;
5660 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
5663 if ((blk > first_block) &&
5664 (blk <= first_block + fs->desc_blocks)) {
5666 pctx->blk = *block_nr;
5667 if (fix_problem(ctx,
5668 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
5670 return BLOCK_CHANGED;
5674 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
5678 if (blk == fs->group_desc[i].bg_block_bitmap) {
5679 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
5680 ctx->invalid_block_bitmap_flag[i]++;
5681 ctx->invalid_bitmaps++;
5685 if (blk == fs->group_desc[i].bg_inode_bitmap) {
5686 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
5687 ctx->invalid_inode_bitmap_flag[i]++;
5688 ctx->invalid_bitmaps++;
5692 if ((blk >= fs->group_desc[i].bg_inode_table) &&
5693 (blk < (fs->group_desc[i].bg_inode_table +
5694 fs->inode_blocks_per_group))) {
5696 * If there are bad blocks in the inode table,
5697 * the inode scan code will try to do
5698 * something reasonable automatically.
5702 first_block += fs->super->s_blocks_per_group;
5705 * If we've gotten to this point, then the only
5706 * possibility is that the bad block inode meta data
5707 * is using a bad block.
5709 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
5710 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
5711 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
5713 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
5715 return BLOCK_CHANGED;
5717 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5724 /* Warn user that the block wasn't claimed */
5725 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
5730 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
5731 const char *name, int num, blk_t *new_block)
5733 ext2_filsys fs = ctx->fs;
5734 blk_t old_block = *new_block;
5737 struct problem_context pctx;
5739 clear_problem_context(&pctx);
5742 pctx.blk = old_block;
5745 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
5746 first_block + fs->super->s_blocks_per_group,
5747 num, ctx->block_found_map, new_block);
5750 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
5751 ext2fs_unmark_valid(fs);
5754 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
5756 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
5757 ext2fs_unmark_valid(fs);
5760 ext2fs_mark_super_dirty(fs);
5761 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
5762 pctx.blk2 = *new_block;
5763 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
5764 PR_1_RELOC_TO), &pctx);
5766 for (i = 0; i < num; i++) {
5768 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
5770 pctx.errcode = io_channel_read_blk(fs->io,
5771 old_block + i, 1, buf);
5773 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
5775 memset(buf, 0, fs->blocksize);
5777 pctx.blk = (*new_block) + i;
5778 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
5781 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
5783 ext2fs_free_mem(&buf);
5787 * This routine gets called at the end of pass 1 if bad blocks are
5788 * detected in the superblock, group descriptors, inode_bitmaps, or
5789 * block bitmaps. At this point, all of the blocks have been mapped
5790 * out, so we can try to allocate new block(s) to replace the bad
5793 static void handle_fs_bad_blocks(e2fsck_t ctx)
5795 ext2_filsys fs = ctx->fs;
5797 int first_block = fs->super->s_first_data_block;
5799 for (i = 0; i < fs->group_desc_count; i++) {
5800 if (ctx->invalid_block_bitmap_flag[i]) {
5801 new_table_block(ctx, first_block, i, _("block bitmap"),
5802 1, &fs->group_desc[i].bg_block_bitmap);
5804 if (ctx->invalid_inode_bitmap_flag[i]) {
5805 new_table_block(ctx, first_block, i, _("inode bitmap"),
5806 1, &fs->group_desc[i].bg_inode_bitmap);
5808 if (ctx->invalid_inode_table_flag[i]) {
5809 new_table_block(ctx, first_block, i, _("inode table"),
5810 fs->inode_blocks_per_group,
5811 &fs->group_desc[i].bg_inode_table);
5812 ctx->flags |= E2F_FLAG_RESTART;
5814 first_block += fs->super->s_blocks_per_group;
5816 ctx->invalid_bitmaps = 0;
5820 * This routine marks all blocks which are used by the superblock,
5821 * group descriptors, inode bitmaps, and block bitmaps.
5823 static void mark_table_blocks(e2fsck_t ctx)
5825 ext2_filsys fs = ctx->fs;
5829 struct problem_context pctx;
5831 clear_problem_context(&pctx);
5833 block = fs->super->s_first_data_block;
5834 for (i = 0; i < fs->group_desc_count; i++) {
5837 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
5840 * Mark the blocks used for the inode table
5842 if (fs->group_desc[i].bg_inode_table) {
5843 for (j = 0, b = fs->group_desc[i].bg_inode_table;
5844 j < fs->inode_blocks_per_group;
5846 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5849 if (fix_problem(ctx,
5850 PR_1_ITABLE_CONFLICT, &pctx)) {
5851 ctx->invalid_inode_table_flag[i]++;
5852 ctx->invalid_bitmaps++;
5855 ext2fs_mark_block_bitmap(ctx->block_found_map,
5862 * Mark block used for the block bitmap
5864 if (fs->group_desc[i].bg_block_bitmap) {
5865 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5866 fs->group_desc[i].bg_block_bitmap)) {
5867 pctx.blk = fs->group_desc[i].bg_block_bitmap;
5868 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
5869 ctx->invalid_block_bitmap_flag[i]++;
5870 ctx->invalid_bitmaps++;
5873 ext2fs_mark_block_bitmap(ctx->block_found_map,
5874 fs->group_desc[i].bg_block_bitmap);
5879 * Mark block used for the inode bitmap
5881 if (fs->group_desc[i].bg_inode_bitmap) {
5882 if (ext2fs_test_block_bitmap(ctx->block_found_map,
5883 fs->group_desc[i].bg_inode_bitmap)) {
5884 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
5885 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
5886 ctx->invalid_inode_bitmap_flag[i]++;
5887 ctx->invalid_bitmaps++;
5890 ext2fs_mark_block_bitmap(ctx->block_found_map,
5891 fs->group_desc[i].bg_inode_bitmap);
5894 block += fs->super->s_blocks_per_group;
5899 * Thes subroutines short circuits ext2fs_get_blocks and
5900 * ext2fs_check_directory; we use them since we already have the inode
5901 * structure, so there's no point in letting the ext2fs library read
5904 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
5907 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5910 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5911 return EXT2_ET_CALLBACK_NOTHANDLED;
5913 for (i=0; i < EXT2_N_BLOCKS; i++)
5914 blocks[i] = ctx->stashed_inode->i_block[i];
5918 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
5919 struct ext2_inode *inode)
5921 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5923 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5924 return EXT2_ET_CALLBACK_NOTHANDLED;
5925 *inode = *ctx->stashed_inode;
5929 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
5930 struct ext2_inode *inode)
5932 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5934 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
5935 *ctx->stashed_inode = *inode;
5936 return EXT2_ET_CALLBACK_NOTHANDLED;
5939 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
5941 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
5943 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
5944 return EXT2_ET_CALLBACK_NOTHANDLED;
5946 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
5947 return EXT2_ET_NO_DIRECTORY;
5951 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
5953 ext2_filsys fs = ctx->fs;
5956 fs->get_blocks = pass1_get_blocks;
5957 fs->check_directory = pass1_check_directory;
5958 fs->read_inode = pass1_read_inode;
5959 fs->write_inode = pass1_write_inode;
5960 ctx->stashed_ino = 0;
5963 fs->check_directory = 0;
5965 fs->write_inode = 0;
5970 * pass1b.c --- Pass #1b of e2fsck
5972 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
5973 * only invoked if pass 1 discovered blocks which are in use by more
5976 * Pass1B scans the data blocks of all the inodes again, generating a
5977 * complete list of duplicate blocks and which inodes have claimed
5980 * Pass1C does a tree-traversal of the filesystem, to determine the
5981 * parent directories of these inodes. This step is necessary so that
5982 * e2fsck can print out the pathnames of affected inodes.
5984 * Pass1D is a reconciliation pass. For each inode with duplicate
5985 * blocks, the user is prompted if s/he would like to clone the file
5986 * (so that the file gets a fresh copy of the duplicated blocks) or
5987 * simply to delete the file.
5992 /* Needed for architectures where sizeof(int) != sizeof(void *) */
5993 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
5994 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
5996 /* Define an extension to the ext2 library's block count information */
5997 #define BLOCK_COUNT_EXTATTR (-5)
6001 struct block_el *next;
6006 struct inode_el *next;
6011 struct inode_el *inode_list;
6015 * This structure stores information about a particular inode which
6016 * is sharing blocks with other inodes. This information is collected
6017 * to display to the user, so that the user knows what files he or she
6018 * is dealing with, when trying to decide how to resolve the conflict
6019 * of multiply-claimed blocks.
6024 struct ext2_inode inode;
6025 struct block_el *block_list;
6028 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
6029 e2_blkcnt_t blockcnt, blk_t ref_blk,
6030 int ref_offset, void *priv_data);
6031 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6032 struct dup_inode *dp, char *block_buf);
6033 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6034 struct dup_inode *dp, char* block_buf);
6035 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
6037 static void pass1b(e2fsck_t ctx, char *block_buf);
6038 static void pass1c(e2fsck_t ctx, char *block_buf);
6039 static void pass1d(e2fsck_t ctx, char *block_buf);
6041 static int dup_inode_count = 0;
6043 static dict_t blk_dict, ino_dict;
6045 static ext2fs_inode_bitmap inode_dup_map;
6047 static int dict_int_cmp(const void *a, const void *b)
6058 * Add a duplicate block record
6060 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
6061 struct ext2_inode *inode)
6064 struct dup_block *db;
6065 struct dup_inode *di;
6066 struct block_el *blk_el;
6067 struct inode_el *ino_el;
6069 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6071 db = (struct dup_block *) dnode_get(n);
6073 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
6074 sizeof(struct dup_block), "duplicate block header");
6077 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
6079 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
6080 sizeof(struct inode_el), "inode element");
6081 ino_el->inode = ino;
6082 ino_el->next = db->inode_list;
6083 db->inode_list = ino_el;
6086 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
6088 di = (struct dup_inode *) dnode_get(n);
6090 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
6091 sizeof(struct dup_inode), "duplicate inode header");
6092 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
6093 di->num_dupblocks = 0;
6096 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
6098 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
6099 sizeof(struct block_el), "block element");
6100 blk_el->block = blk;
6101 blk_el->next = di->block_list;
6102 di->block_list = blk_el;
6103 di->num_dupblocks++;
6107 * Free a duplicate inode record
6109 static void inode_dnode_free(dnode_t *node)
6111 struct dup_inode *di;
6112 struct block_el *p, *next;
6114 di = (struct dup_inode *) dnode_get(node);
6115 for (p = di->block_list; p; p = next) {
6123 * Free a duplicate block record
6125 static void block_dnode_free(dnode_t *node)
6127 struct dup_block *db;
6128 struct inode_el *p, *next;
6130 db = (struct dup_block *) dnode_get(node);
6131 for (p = db->inode_list; p; p = next) {
6140 * Main procedure for handling duplicate blocks
6142 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
6144 ext2_filsys fs = ctx->fs;
6145 struct problem_context pctx;
6147 clear_problem_context(&pctx);
6149 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
6150 _("multiply claimed inode map"), &inode_dup_map);
6152 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
6153 ctx->flags |= E2F_FLAG_ABORT;
6157 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6158 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6159 dict_set_allocator(&ino_dict, inode_dnode_free);
6160 dict_set_allocator(&blk_dict, block_dnode_free);
6162 pass1b(ctx, block_buf);
6163 pass1c(ctx, block_buf);
6164 pass1d(ctx, block_buf);
6167 * Time to free all of the accumulated data structures that we
6168 * don't need anymore.
6170 dict_free_nodes(&ino_dict);
6171 dict_free_nodes(&blk_dict);
6175 * Scan the inodes looking for inodes that contain duplicate blocks.
6177 struct process_block_struct_1b {
6181 struct ext2_inode *inode;
6182 struct problem_context *pctx;
6185 static void pass1b(e2fsck_t ctx, char *block_buf)
6187 ext2_filsys fs = ctx->fs;
6189 struct ext2_inode inode;
6190 ext2_inode_scan scan;
6191 struct process_block_struct_1b pb;
6192 struct problem_context pctx;
6194 clear_problem_context(&pctx);
6196 if (!(ctx->options & E2F_OPT_PREEN))
6197 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
6198 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
6201 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6202 ctx->flags |= E2F_FLAG_ABORT;
6205 ctx->stashed_inode = &inode;
6208 pctx.str = "pass1b";
6210 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
6211 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
6214 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6215 ctx->flags |= E2F_FLAG_ABORT;
6220 pctx.ino = ctx->stashed_ino = ino;
6221 if ((ino != EXT2_BAD_INO) &&
6222 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
6229 if (ext2fs_inode_has_valid_blocks(&inode) ||
6230 (ino == EXT2_BAD_INO))
6231 pctx.errcode = ext2fs_block_iterate2(fs, ino,
6232 0, block_buf, process_pass1b_block, &pb);
6233 if (inode.i_file_acl)
6234 process_pass1b_block(fs, &inode.i_file_acl,
6235 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6236 if (pb.dup_blocks) {
6237 end_problem_latch(ctx, PR_LATCH_DBLOCK);
6238 if (ino >= EXT2_FIRST_INODE(fs->super) ||
6239 ino == EXT2_ROOT_INO)
6243 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6245 ext2fs_close_inode_scan(scan);
6246 e2fsck_use_inode_shortcuts(ctx, 0);
6249 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
6251 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6252 blk_t ref_blk FSCK_ATTR((unused)),
6253 int ref_offset FSCK_ATTR((unused)),
6256 struct process_block_struct_1b *p;
6259 if (HOLE_BLKADDR(*block_nr))
6261 p = (struct process_block_struct_1b *) priv_data;
6264 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
6267 /* OK, this is a duplicate block */
6268 if (p->ino != EXT2_BAD_INO) {
6269 p->pctx->blk = *block_nr;
6270 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
6273 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
6275 add_dupe(ctx, p->ino, *block_nr, p->inode);
6281 * Pass 1c: Scan directories for inodes with duplicate blocks. This
6282 * is used so that we can print pathnames when prompting the user for
6285 struct search_dir_struct {
6287 ext2_ino_t first_inode;
6288 ext2_ino_t max_inode;
6291 static int search_dirent_proc(ext2_ino_t dir, int entry,
6292 struct ext2_dir_entry *dirent,
6293 int offset FSCK_ATTR((unused)),
6294 int blocksize FSCK_ATTR((unused)),
6295 char *buf FSCK_ATTR((unused)),
6298 struct search_dir_struct *sd;
6299 struct dup_inode *p;
6302 sd = (struct search_dir_struct *) priv_data;
6304 if (dirent->inode > sd->max_inode)
6305 /* Should abort this inode, but not everything */
6308 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
6309 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
6312 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
6315 p = (struct dup_inode *) dnode_get(n);
6319 return(sd->count ? 0 : DIRENT_ABORT);
6323 static void pass1c(e2fsck_t ctx, char *block_buf)
6325 ext2_filsys fs = ctx->fs;
6326 struct search_dir_struct sd;
6327 struct problem_context pctx;
6329 clear_problem_context(&pctx);
6331 if (!(ctx->options & E2F_OPT_PREEN))
6332 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
6335 * Search through all directories to translate inodes to names
6336 * (by searching for the containing directory for that inode.)
6338 sd.count = dup_inode_count;
6339 sd.first_inode = EXT2_FIRST_INODE(fs->super);
6340 sd.max_inode = fs->super->s_inodes_count;
6341 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
6342 search_dirent_proc, &sd);
6345 static void pass1d(e2fsck_t ctx, char *block_buf)
6347 ext2_filsys fs = ctx->fs;
6348 struct dup_inode *p, *t;
6349 struct dup_block *q;
6350 ext2_ino_t *shared, ino;
6355 struct problem_context pctx;
6360 clear_problem_context(&pctx);
6362 if (!(ctx->options & E2F_OPT_PREEN))
6363 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
6364 e2fsck_read_bitmaps(ctx);
6366 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
6367 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
6368 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
6369 sizeof(ext2_ino_t) * dict_count(&ino_dict),
6370 "Shared inode list");
6371 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
6372 p = (struct dup_inode *) dnode_get(n);
6375 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
6376 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
6380 * Find all of the inodes which share blocks with this
6381 * one. First we find all of the duplicate blocks
6382 * belonging to this inode, and then search each block
6383 * get the list of inodes, and merge them together.
6385 for (s = p->block_list; s; s = s->next) {
6386 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
6388 continue; /* Should never happen... */
6389 q = (struct dup_block *) dnode_get(m);
6392 if (check_if_fs_block(ctx, s->block)) {
6398 * Add all inodes used by this block to the
6399 * shared[] --- which is a unique list, so
6400 * if an inode is already in shared[], don't
6403 for (r = q->inode_list; r; r = r->next) {
6404 if (r->inode == ino)
6406 for (i = 0; i < shared_len; i++)
6407 if (shared[i] == r->inode)
6409 if (i == shared_len) {
6410 shared[shared_len++] = r->inode;
6416 * Report the inode that we are working on
6418 pctx.inode = &p->inode;
6421 pctx.blkcount = p->num_dupblocks;
6422 pctx.num = meta_data ? shared_len+1 : shared_len;
6423 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
6428 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
6430 for (i = 0; i < shared_len; i++) {
6431 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
6433 continue; /* should never happen */
6434 t = (struct dup_inode *) dnode_get(m);
6436 * Report the inode that we are sharing with
6438 pctx.inode = &t->inode;
6439 pctx.ino = shared[i];
6441 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
6444 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
6447 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
6448 pctx.errcode = clone_file(ctx, ino, p, block_buf);
6450 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
6454 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
6455 delete_file(ctx, ino, p, block_buf);
6457 ext2fs_unmark_valid(fs);
6459 ext2fs_free_mem(&shared);
6463 * Drop the refcount on the dup_block structure, and clear the entry
6464 * in the block_dup_map if appropriate.
6466 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
6469 if (p->num_bad <= 0 ||
6470 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
6471 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
6474 static int delete_file_block(ext2_filsys fs,
6476 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6477 blk_t ref_block FSCK_ATTR((unused)),
6478 int ref_offset FSCK_ATTR((unused)),
6481 struct process_block_struct_1b *pb;
6482 struct dup_block *p;
6486 pb = (struct process_block_struct_1b *) priv_data;
6489 if (HOLE_BLKADDR(*block_nr))
6492 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6493 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6495 p = (struct dup_block *) dnode_get(n);
6496 decrement_badcount(ctx, *block_nr, p);
6498 com_err("delete_file_block", 0,
6499 _("internal error; can't find dup_blk for %d\n"),
6502 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6503 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6509 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6510 struct dup_inode *dp, char* block_buf)
6512 ext2_filsys fs = ctx->fs;
6513 struct process_block_struct_1b pb;
6514 struct ext2_inode inode;
6515 struct problem_context pctx;
6518 clear_problem_context(&pctx);
6519 pctx.ino = pb.ino = ino;
6520 pb.dup_blocks = dp->num_dupblocks;
6522 pctx.str = "delete_file";
6524 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6525 if (ext2fs_inode_has_valid_blocks(&inode))
6526 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6527 delete_file_block, &pb);
6529 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6530 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6531 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6532 if (ctx->inode_bad_map)
6533 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6534 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6536 /* Inode may have changed by block_iterate, so reread it */
6537 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6538 inode.i_links_count = 0;
6539 inode.i_dtime = time(0);
6540 if (inode.i_file_acl &&
6541 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6543 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6544 block_buf, -1, &count);
6545 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6550 pctx.blk = inode.i_file_acl;
6551 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
6554 * If the count is zero, then arrange to have the
6555 * block deleted. If the block is in the block_dup_map,
6556 * also call delete_file_block since it will take care
6557 * of keeping the accounting straight.
6560 ext2fs_test_block_bitmap(ctx->block_dup_map,
6562 delete_file_block(fs, &inode.i_file_acl,
6563 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6565 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
6568 struct clone_struct {
6575 static int clone_file_block(ext2_filsys fs,
6577 e2_blkcnt_t blockcnt,
6578 blk_t ref_block FSCK_ATTR((unused)),
6579 int ref_offset FSCK_ATTR((unused)),
6582 struct dup_block *p;
6585 struct clone_struct *cs = (struct clone_struct *) priv_data;
6591 if (HOLE_BLKADDR(*block_nr))
6594 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6595 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6597 p = (struct dup_block *) dnode_get(n);
6598 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
6601 cs->errcode = retval;
6604 if (cs->dir && (blockcnt >= 0)) {
6605 retval = ext2fs_set_dir_block(fs->dblist,
6606 cs->dir, new_block, blockcnt);
6608 cs->errcode = retval;
6613 printf("Cloning block %u to %u\n", *block_nr,
6616 retval = io_channel_read_blk(fs->io, *block_nr, 1,
6619 cs->errcode = retval;
6622 retval = io_channel_write_blk(fs->io, new_block, 1,
6625 cs->errcode = retval;
6628 decrement_badcount(ctx, *block_nr, p);
6629 *block_nr = new_block;
6630 ext2fs_mark_block_bitmap(ctx->block_found_map,
6632 ext2fs_mark_block_bitmap(fs->block_map, new_block);
6633 return BLOCK_CHANGED;
6635 com_err("clone_file_block", 0,
6636 _("internal error; can't find dup_blk for %d\n"),
6642 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6643 struct dup_inode *dp, char* block_buf)
6645 ext2_filsys fs = ctx->fs;
6647 struct clone_struct cs;
6648 struct problem_context pctx;
6651 struct inode_el *ino_el;
6652 struct dup_block *db;
6653 struct dup_inode *di;
6655 clear_problem_context(&pctx);
6659 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
6663 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
6667 pctx.str = "clone_file";
6668 if (ext2fs_inode_has_valid_blocks(&dp->inode))
6669 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6670 clone_file_block, &cs);
6671 ext2fs_mark_bb_dirty(fs);
6673 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6674 retval = pctx.errcode;
6678 com_err("clone_file", cs.errcode,
6679 _("returned from clone_file_block"));
6680 retval = cs.errcode;
6683 /* The inode may have changed on disk, so we have to re-read it */
6684 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
6685 blk = dp->inode.i_file_acl;
6686 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
6687 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
6689 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
6691 * If we cloned the EA block, find all other inodes
6692 * which refered to that EA block, and modify
6693 * them to point to the new EA block.
6695 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6696 db = (struct dup_block *) dnode_get(n);
6697 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
6698 if (ino_el->inode == ino)
6700 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
6701 di = (struct dup_inode *) dnode_get(n);
6702 if (di->inode.i_file_acl == blk) {
6703 di->inode.i_file_acl = dp->inode.i_file_acl;
6704 e2fsck_write_inode(ctx, ino_el->inode,
6705 &di->inode, "clone file EA");
6706 decrement_badcount(ctx, blk, db);
6712 ext2fs_free_mem(&cs.buf);
6717 * This routine returns 1 if a block overlaps with one of the superblocks,
6718 * group descriptors, inode bitmaps, or block bitmaps.
6720 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
6722 ext2_filsys fs = ctx->fs;
6726 block = fs->super->s_first_data_block;
6727 for (i = 0; i < fs->group_desc_count; i++) {
6729 /* Check superblocks/block group descriptros */
6730 if (ext2fs_bg_has_super(fs, i)) {
6731 if (test_block >= block &&
6732 (test_block <= block + fs->desc_blocks))
6736 /* Check the inode table */
6737 if ((fs->group_desc[i].bg_inode_table) &&
6738 (test_block >= fs->group_desc[i].bg_inode_table) &&
6739 (test_block < (fs->group_desc[i].bg_inode_table +
6740 fs->inode_blocks_per_group)))
6743 /* Check the bitmap blocks */
6744 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
6745 (test_block == fs->group_desc[i].bg_inode_bitmap))
6748 block += fs->super->s_blocks_per_group;
6753 * pass2.c --- check directory structure
6755 * Pass 2 of e2fsck iterates through all active directory inodes, and
6756 * applies to following tests to each directory entry in the directory
6757 * blocks in the inodes:
6759 * - The length of the directory entry (rec_len) should be at
6760 * least 8 bytes, and no more than the remaining space
6761 * left in the directory block.
6762 * - The length of the name in the directory entry (name_len)
6763 * should be less than (rec_len - 8).
6764 * - The inode number in the directory entry should be within
6766 * - The inode number should refer to a in-use inode.
6767 * - The first entry should be '.', and its inode should be
6768 * the inode of the directory.
6769 * - The second entry should be '..'.
6771 * To minimize disk seek time, the directory blocks are processed in
6772 * sorted order of block numbers.
6774 * Pass 2 also collects the following information:
6775 * - The inode numbers of the subdirectories for each directory.
6777 * Pass 2 relies on the following information from previous passes:
6778 * - The directory information collected in pass 1.
6779 * - The inode_used_map bitmap
6780 * - The inode_bad_map bitmap
6781 * - The inode_dir_map bitmap
6783 * Pass 2 frees the following data structures
6784 * - The inode_bad_map bitmap
6785 * - The inode_reg_map bitmap
6788 /* #define DX_DEBUG */
6791 * Keeps track of how many times an inode is referenced.
6793 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
6794 static int check_dir_block(ext2_filsys fs,
6795 struct ext2_db_entry *dir_blocks_info,
6797 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
6798 struct problem_context *pctx);
6799 static int update_dir_block(ext2_filsys fs,
6801 e2_blkcnt_t blockcnt,
6805 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
6806 static int htree_depth(struct dx_dir_info *dx_dir,
6807 struct dx_dirblock_info *dx_db);
6808 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
6810 struct check_dir_struct {
6812 struct problem_context pctx;
6817 static void e2fsck_pass2(e2fsck_t ctx)
6819 struct ext2_super_block *sb = ctx->fs->super;
6820 struct problem_context pctx;
6821 ext2_filsys fs = ctx->fs;
6823 #ifdef RESOURCE_TRACK
6824 struct resource_track rtrack;
6826 struct dir_info *dir;
6827 struct check_dir_struct cd;
6828 struct dx_dir_info *dx_dir;
6829 struct dx_dirblock_info *dx_db, *dx_parent;
6835 #ifdef RESOURCE_TRACK
6836 init_resource_track(&rtrack);
6839 clear_problem_context(&cd.pctx);
6842 mtrace_print("Pass 2");
6845 if (!(ctx->options & E2F_OPT_PREEN))
6846 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
6848 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
6849 0, ctx->inode_link_info,
6851 if (cd.pctx.errcode) {
6852 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
6853 ctx->flags |= E2F_FLAG_ABORT;
6856 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
6857 "directory scan buffer");
6860 * Set up the parent pointer for the root directory, if
6861 * present. (If the root directory is not present, we will
6862 * create it in pass 3.)
6864 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
6866 dir->parent = EXT2_ROOT_INO;
6871 cd.max = ext2fs_dblist_count(fs->dblist);
6874 (void) (ctx->progress)(ctx, 2, 0, cd.max);
6876 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
6877 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
6879 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
6881 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6883 if (cd.pctx.errcode) {
6884 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
6885 ctx->flags |= E2F_FLAG_ABORT;
6890 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
6891 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6893 if (dx_dir->numblocks == 0)
6895 clear_problem_context(&pctx);
6897 pctx.dir = dx_dir->ino;
6898 dx_db = dx_dir->dx_block;
6899 if (dx_db->flags & DX_FLAG_REFERENCED)
6900 dx_db->flags |= DX_FLAG_DUP_REF;
6902 dx_db->flags |= DX_FLAG_REFERENCED;
6904 * Find all of the first and last leaf blocks, and
6905 * update their parent's min and max hash values
6907 for (b=0, dx_db = dx_dir->dx_block;
6908 b < dx_dir->numblocks;
6910 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
6911 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
6913 dx_parent = &dx_dir->dx_block[dx_db->parent];
6915 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
6917 if (dx_db->flags & DX_FLAG_FIRST)
6918 dx_parent->min_hash = dx_db->min_hash;
6920 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
6922 if (dx_db->flags & DX_FLAG_LAST)
6923 dx_parent->max_hash = dx_db->max_hash;
6926 for (b=0, dx_db = dx_dir->dx_block;
6927 b < dx_dir->numblocks;
6930 pctx.group = dx_db->parent;
6932 if (!(dx_db->flags & DX_FLAG_FIRST) &&
6933 (dx_db->min_hash < dx_db->node_min_hash)) {
6934 pctx.blk = dx_db->min_hash;
6935 pctx.blk2 = dx_db->node_min_hash;
6936 code = PR_2_HTREE_MIN_HASH;
6937 fix_problem(ctx, code, &pctx);
6940 if (dx_db->type == DX_DIRBLOCK_LEAF) {
6941 depth = htree_depth(dx_dir, dx_db);
6942 if (depth != dx_dir->depth) {
6943 code = PR_2_HTREE_BAD_DEPTH;
6944 fix_problem(ctx, code, &pctx);
6949 * This test doesn't apply for the root block
6953 (dx_db->max_hash > dx_db->node_max_hash)) {
6954 pctx.blk = dx_db->max_hash;
6955 pctx.blk2 = dx_db->node_max_hash;
6956 code = PR_2_HTREE_MAX_HASH;
6957 fix_problem(ctx, code, &pctx);
6960 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
6961 code = PR_2_HTREE_NOTREF;
6962 fix_problem(ctx, code, &pctx);
6964 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
6965 code = PR_2_HTREE_DUPREF;
6966 fix_problem(ctx, code, &pctx);
6972 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
6973 clear_htree(ctx, dx_dir->ino);
6974 dx_dir->numblocks = 0;
6978 ext2fs_free_mem(&buf);
6979 ext2fs_free_dblist(fs->dblist);
6981 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
6982 ctx->inode_bad_map = 0;
6983 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
6984 ctx->inode_reg_map = 0;
6986 clear_problem_context(&pctx);
6987 if (ctx->large_files) {
6988 if (!(sb->s_feature_ro_compat &
6989 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
6990 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
6991 sb->s_feature_ro_compat |=
6992 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6993 ext2fs_mark_super_dirty(fs);
6995 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
6996 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
6997 ext2fs_update_dynamic_rev(fs);
6998 ext2fs_mark_super_dirty(fs);
7000 } else if (!ctx->large_files &&
7001 (sb->s_feature_ro_compat &
7002 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
7003 if (fs->flags & EXT2_FLAG_RW) {
7004 sb->s_feature_ro_compat &=
7005 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7006 ext2fs_mark_super_dirty(fs);
7010 #ifdef RESOURCE_TRACK
7011 if (ctx->options & E2F_OPT_TIME2) {
7012 e2fsck_clear_progbar(ctx);
7013 print_resource_track(_("Pass 2"), &rtrack);
7018 #define MAX_DEPTH 32000
7019 static int htree_depth(struct dx_dir_info *dx_dir,
7020 struct dx_dirblock_info *dx_db)
7024 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
7025 dx_db = &dx_dir->dx_block[dx_db->parent];
7031 static int dict_de_cmp(const void *a, const void *b)
7033 const struct ext2_dir_entry *de_a, *de_b;
7036 de_a = (const struct ext2_dir_entry *) a;
7037 a_len = de_a->name_len & 0xFF;
7038 de_b = (const struct ext2_dir_entry *) b;
7039 b_len = de_b->name_len & 0xFF;
7042 return (a_len - b_len);
7044 return strncmp(de_a->name, de_b->name, a_len);
7048 * This is special sort function that makes sure that directory blocks
7049 * with a dirblock of zero are sorted to the beginning of the list.
7050 * This guarantees that the root node of the htree directories are
7051 * processed first, so we know what hash version to use.
7053 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
7055 const struct ext2_db_entry *db_a =
7056 (const struct ext2_db_entry *) a;
7057 const struct ext2_db_entry *db_b =
7058 (const struct ext2_db_entry *) b;
7060 if (db_a->blockcnt && !db_b->blockcnt)
7063 if (!db_a->blockcnt && db_b->blockcnt)
7066 if (db_a->blk != db_b->blk)
7067 return (int) (db_a->blk - db_b->blk);
7069 if (db_a->ino != db_b->ino)
7070 return (int) (db_a->ino - db_b->ino);
7072 return (int) (db_a->blockcnt - db_b->blockcnt);
7077 * Make sure the first entry in the directory is '.', and that the
7078 * directory entry is sane.
7080 static int check_dot(e2fsck_t ctx,
7081 struct ext2_dir_entry *dirent,
7082 ext2_ino_t ino, struct problem_context *pctx)
7084 struct ext2_dir_entry *nextdir;
7091 problem = PR_2_MISSING_DOT;
7092 else if (((dirent->name_len & 0xFF) != 1) ||
7093 (dirent->name[0] != '.'))
7094 problem = PR_2_1ST_NOT_DOT;
7095 else if (dirent->name[1] != '\0')
7096 problem = PR_2_DOT_NULL_TERM;
7099 if (fix_problem(ctx, problem, pctx)) {
7100 if (dirent->rec_len < 12)
7101 dirent->rec_len = 12;
7102 dirent->inode = ino;
7103 dirent->name_len = 1;
7104 dirent->name[0] = '.';
7105 dirent->name[1] = '\0';
7110 if (dirent->inode != ino) {
7111 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
7112 dirent->inode = ino;
7116 if (dirent->rec_len > 12) {
7117 new_len = dirent->rec_len - 12;
7120 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
7121 nextdir = (struct ext2_dir_entry *)
7122 ((char *) dirent + 12);
7123 dirent->rec_len = 12;
7124 nextdir->rec_len = new_len;
7126 nextdir->name_len = 0;
7135 * Make sure the second entry in the directory is '..', and that the
7136 * directory entry is sane. We do not check the inode number of '..'
7137 * here; this gets done in pass 3.
7139 static int check_dotdot(e2fsck_t ctx,
7140 struct ext2_dir_entry *dirent,
7141 struct dir_info *dir, struct problem_context *pctx)
7146 problem = PR_2_MISSING_DOT_DOT;
7147 else if (((dirent->name_len & 0xFF) != 2) ||
7148 (dirent->name[0] != '.') ||
7149 (dirent->name[1] != '.'))
7150 problem = PR_2_2ND_NOT_DOT_DOT;
7151 else if (dirent->name[2] != '\0')
7152 problem = PR_2_DOT_DOT_NULL_TERM;
7155 if (fix_problem(ctx, problem, pctx)) {
7156 if (dirent->rec_len < 12)
7157 dirent->rec_len = 12;
7159 * Note: we don't have the parent inode just
7160 * yet, so we will fill it in with the root
7161 * inode. This will get fixed in pass 3.
7163 dirent->inode = EXT2_ROOT_INO;
7164 dirent->name_len = 2;
7165 dirent->name[0] = '.';
7166 dirent->name[1] = '.';
7167 dirent->name[2] = '\0';
7172 dir->dotdot = dirent->inode;
7177 * Check to make sure a directory entry doesn't contain any illegal
7180 static int check_name(e2fsck_t ctx,
7181 struct ext2_dir_entry *dirent,
7182 struct problem_context *pctx)
7188 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
7189 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
7191 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
7194 dirent->name[i] = '.';
7203 * Check the directory filetype (if present)
7207 * Given a mode, return the ext2 file type
7209 static int ext2_file_type(unsigned int mode)
7211 if (LINUX_S_ISREG(mode))
7212 return EXT2_FT_REG_FILE;
7214 if (LINUX_S_ISDIR(mode))
7217 if (LINUX_S_ISCHR(mode))
7218 return EXT2_FT_CHRDEV;
7220 if (LINUX_S_ISBLK(mode))
7221 return EXT2_FT_BLKDEV;
7223 if (LINUX_S_ISLNK(mode))
7224 return EXT2_FT_SYMLINK;
7226 if (LINUX_S_ISFIFO(mode))
7227 return EXT2_FT_FIFO;
7229 if (LINUX_S_ISSOCK(mode))
7230 return EXT2_FT_SOCK;
7235 static _INLINE_ int check_filetype(e2fsck_t ctx,
7236 struct ext2_dir_entry *dirent,
7237 struct problem_context *pctx)
7239 int filetype = dirent->name_len >> 8;
7240 int should_be = EXT2_FT_UNKNOWN;
7241 struct ext2_inode inode;
7243 if (!(ctx->fs->super->s_feature_incompat &
7244 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
7245 if (filetype == 0 ||
7246 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
7248 dirent->name_len = dirent->name_len & 0xFF;
7252 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
7253 should_be = EXT2_FT_DIR;
7254 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
7256 should_be = EXT2_FT_REG_FILE;
7257 } else if (ctx->inode_bad_map &&
7258 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7262 e2fsck_read_inode(ctx, dirent->inode, &inode,
7264 should_be = ext2_file_type(inode.i_mode);
7266 if (filetype == should_be)
7268 pctx->num = should_be;
7270 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
7274 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
7279 static void parse_int_node(ext2_filsys fs,
7280 struct ext2_db_entry *db,
7281 struct check_dir_struct *cd,
7282 struct dx_dir_info *dx_dir,
7285 struct ext2_dx_root_info *root;
7286 struct ext2_dx_entry *ent;
7287 struct ext2_dx_countlimit *limit;
7288 struct dx_dirblock_info *dx_db;
7289 int i, expect_limit, count;
7291 ext2_dirhash_t min_hash = 0xffffffff;
7292 ext2_dirhash_t max_hash = 0;
7293 ext2_dirhash_t hash = 0, prev_hash;
7295 if (db->blockcnt == 0) {
7296 root = (struct ext2_dx_root_info *) (block_buf + 24);
7299 printf("Root node dump:\n");
7300 printf("\t Reserved zero: %d\n", root->reserved_zero);
7301 printf("\t Hash Version: %d\n", root->hash_version);
7302 printf("\t Info length: %d\n", root->info_length);
7303 printf("\t Indirect levels: %d\n", root->indirect_levels);
7304 printf("\t Flags: %d\n", root->unused_flags);
7307 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
7309 ent = (struct ext2_dx_entry *) (block_buf+8);
7311 limit = (struct ext2_dx_countlimit *) ent;
7314 printf("Number of entries (count): %d\n",
7315 ext2fs_le16_to_cpu(limit->count));
7316 printf("Number of entries (limit): %d\n",
7317 ext2fs_le16_to_cpu(limit->limit));
7320 count = ext2fs_le16_to_cpu(limit->count);
7321 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
7322 sizeof(struct ext2_dx_entry);
7323 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
7324 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
7325 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
7326 goto clear_and_exit;
7328 if (count > expect_limit) {
7329 cd->pctx.num = count;
7330 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
7331 goto clear_and_exit;
7332 count = expect_limit;
7335 for (i=0; i < count; i++) {
7337 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
7339 printf("Entry #%d: Hash 0x%08x, block %d\n", i,
7340 hash, ext2fs_le32_to_cpu(ent[i].block));
7342 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
7343 /* Check to make sure the block is valid */
7344 if (blk > (blk_t) dx_dir->numblocks) {
7346 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
7348 goto clear_and_exit;
7350 if (hash < prev_hash &&
7351 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
7352 goto clear_and_exit;
7353 dx_db = &dx_dir->dx_block[blk];
7354 if (dx_db->flags & DX_FLAG_REFERENCED) {
7355 dx_db->flags |= DX_FLAG_DUP_REF;
7357 dx_db->flags |= DX_FLAG_REFERENCED;
7358 dx_db->parent = db->blockcnt;
7360 if (hash < min_hash)
7362 if (hash > max_hash)
7364 dx_db->node_min_hash = hash;
7366 dx_db->node_max_hash =
7367 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
7369 dx_db->node_max_hash = 0xfffffffe;
7370 dx_db->flags |= DX_FLAG_LAST;
7373 dx_db->flags |= DX_FLAG_FIRST;
7376 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
7377 db->blockcnt, min_hash, max_hash);
7379 dx_db = &dx_dir->dx_block[db->blockcnt];
7380 dx_db->min_hash = min_hash;
7381 dx_db->max_hash = max_hash;
7385 clear_htree(cd->ctx, cd->pctx.ino);
7386 dx_dir->numblocks = 0;
7388 #endif /* ENABLE_HTREE */
7391 * Given a busted directory, try to salvage it somehow.
7394 static void salvage_directory(ext2_filsys fs,
7395 struct ext2_dir_entry *dirent,
7396 struct ext2_dir_entry *prev,
7397 unsigned int *offset)
7399 char *cp = (char *) dirent;
7400 int left = fs->blocksize - *offset - dirent->rec_len;
7401 int name_len = dirent->name_len & 0xFF;
7404 * Special case of directory entry of size 8: copy what's left
7405 * of the directory block up to cover up the invalid hole.
7407 if ((left >= 12) && (dirent->rec_len == 8)) {
7408 memmove(cp, cp+8, left);
7409 memset(cp + left, 0, 8);
7413 * If the directory entry overruns the end of the directory
7414 * block, and the name is small enough to fit, then adjust the
7418 (name_len + 8 <= dirent->rec_len + left) &&
7419 dirent->inode <= fs->super->s_inodes_count &&
7420 strnlen(dirent->name, name_len) == name_len) {
7421 dirent->rec_len += left;
7425 * If the directory entry is a multiple of four, so it is
7426 * valid, let the previous directory entry absorb the invalid
7429 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
7430 prev->rec_len += dirent->rec_len;
7431 *offset += dirent->rec_len;
7435 * Default salvage method --- kill all of the directory
7436 * entries for the rest of the block. We will either try to
7437 * absorb it into the previous directory entry, or create a
7438 * new empty directory entry the rest of the directory block.
7441 prev->rec_len += fs->blocksize - *offset;
7442 *offset = fs->blocksize;
7444 dirent->rec_len = fs->blocksize - *offset;
7445 dirent->name_len = 0;
7450 static int check_dir_block(ext2_filsys fs,
7451 struct ext2_db_entry *db,
7454 struct dir_info *subdir, *dir;
7455 struct dx_dir_info *dx_dir;
7457 struct dx_dirblock_info *dx_db = 0;
7458 #endif /* ENABLE_HTREE */
7459 struct ext2_dir_entry *dirent, *prev;
7460 ext2_dirhash_t hash;
7461 unsigned int offset = 0;
7462 int dir_modified = 0;
7464 blk_t block_nr = db->blk;
7465 ext2_ino_t ino = db->ino;
7467 struct check_dir_struct *cd;
7471 struct ext2_dx_root_info *root;
7472 struct ext2_dx_countlimit *limit;
7473 static dict_t de_dict;
7474 struct problem_context pctx;
7477 cd = (struct check_dir_struct *) priv_data;
7481 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7482 return DIRENT_ABORT;
7484 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
7485 return DIRENT_ABORT;
7488 * Make sure the inode is still in use (could have been
7489 * deleted in the duplicate/bad blocks pass.
7491 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
7495 cd->pctx.blk = block_nr;
7496 cd->pctx.blkcount = db->blockcnt;
7498 cd->pctx.dirent = 0;
7502 if (allocate_dir_block(ctx, db, &cd->pctx))
7512 if (ctx->dirs_to_hash &&
7513 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
7517 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr,
7521 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
7522 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
7523 cd->pctx.errcode = 0; /* We'll handle this ourselves */
7524 if (cd->pctx.errcode) {
7525 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
7526 ctx->flags |= E2F_FLAG_ABORT;
7527 return DIRENT_ABORT;
7529 memset(buf, 0, fs->blocksize);
7532 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
7533 if (dx_dir && dx_dir->numblocks) {
7534 if (db->blockcnt >= dx_dir->numblocks) {
7535 printf("XXX should never happen!!!\n");
7538 dx_db = &dx_dir->dx_block[db->blockcnt];
7539 dx_db->type = DX_DIRBLOCK_LEAF;
7540 dx_db->phys = block_nr;
7541 dx_db->min_hash = ~0;
7542 dx_db->max_hash = 0;
7544 dirent = (struct ext2_dir_entry *) buf;
7545 limit = (struct ext2_dx_countlimit *) (buf+8);
7546 if (db->blockcnt == 0) {
7547 root = (struct ext2_dx_root_info *) (buf + 24);
7548 dx_db->type = DX_DIRBLOCK_ROOT;
7549 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
7550 if ((root->reserved_zero ||
7551 root->info_length < 8 ||
7552 root->indirect_levels > 1) &&
7553 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
7554 clear_htree(ctx, ino);
7555 dx_dir->numblocks = 0;
7558 dx_dir->hashversion = root->hash_version;
7559 dx_dir->depth = root->indirect_levels + 1;
7560 } else if ((dirent->inode == 0) &&
7561 (dirent->rec_len == fs->blocksize) &&
7562 (dirent->name_len == 0) &&
7563 (ext2fs_le16_to_cpu(limit->limit) ==
7564 ((fs->blocksize-8) /
7565 sizeof(struct ext2_dx_entry))))
7566 dx_db->type = DX_DIRBLOCK_NODE;
7568 #endif /* ENABLE_HTREE */
7570 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
7574 dirent = (struct ext2_dir_entry *) (buf + offset);
7575 cd->pctx.dirent = dirent;
7576 cd->pctx.num = offset;
7577 if (((offset + dirent->rec_len) > fs->blocksize) ||
7578 (dirent->rec_len < 12) ||
7579 ((dirent->rec_len % 4) != 0) ||
7580 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
7581 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
7582 salvage_directory(fs, dirent, prev, &offset);
7586 goto abort_free_dict;
7588 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
7589 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
7590 dirent->name_len = EXT2_NAME_LEN;
7595 if (dot_state == 0) {
7596 if (check_dot(ctx, dirent, ino, &cd->pctx))
7598 } else if (dot_state == 1) {
7599 dir = e2fsck_get_dir_info(ctx, ino);
7601 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
7602 goto abort_free_dict;
7604 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
7606 } else if (dirent->inode == ino) {
7607 problem = PR_2_LINK_DOT;
7608 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
7618 * Make sure the inode listed is a legal one.
7620 if (((dirent->inode != EXT2_ROOT_INO) &&
7621 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
7622 (dirent->inode > fs->super->s_inodes_count)) {
7623 problem = PR_2_BAD_INO;
7624 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
7627 * If the inode is unused, offer to clear it.
7629 problem = PR_2_UNUSED_INODE;
7630 } else if (ctx->inode_bb_map &&
7631 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
7634 * If the inode is in a bad block, offer to
7637 problem = PR_2_BB_INODE;
7638 } else if ((dot_state > 1) &&
7639 ((dirent->name_len & 0xFF) == 1) &&
7640 (dirent->name[0] == '.')) {
7642 * If there's a '.' entry in anything other
7643 * than the first directory entry, it's a
7644 * duplicate entry that should be removed.
7646 problem = PR_2_DUP_DOT;
7647 } else if ((dot_state > 1) &&
7648 ((dirent->name_len & 0xFF) == 2) &&
7649 (dirent->name[0] == '.') &&
7650 (dirent->name[1] == '.')) {
7652 * If there's a '..' entry in anything other
7653 * than the second directory entry, it's a
7654 * duplicate entry that should be removed.
7656 problem = PR_2_DUP_DOT_DOT;
7657 } else if ((dot_state > 1) &&
7658 (dirent->inode == EXT2_ROOT_INO)) {
7660 * Don't allow links to the root directory.
7661 * We check this specially to make sure we
7662 * catch this error case even if the root
7663 * directory hasn't been created yet.
7665 problem = PR_2_LINK_ROOT;
7666 } else if ((dot_state > 1) &&
7667 (dirent->name_len & 0xFF) == 0) {
7669 * Don't allow zero-length directory names.
7671 problem = PR_2_NULL_NAME;
7675 if (fix_problem(ctx, problem, &cd->pctx)) {
7680 ext2fs_unmark_valid(fs);
7681 if (problem == PR_2_BAD_INO)
7687 * If the inode was marked as having bad fields in
7688 * pass1, process it and offer to fix/clear it.
7689 * (We wait until now so that we can display the
7690 * pathname to the user.)
7692 if (ctx->inode_bad_map &&
7693 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7695 if (e2fsck_process_bad_inode(ctx, ino,
7697 buf + fs->blocksize)) {
7702 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7703 return DIRENT_ABORT;
7706 if (check_name(ctx, dirent, &cd->pctx))
7709 if (check_filetype(ctx, dirent, &cd->pctx))
7714 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
7715 (dirent->name_len & 0xFF),
7716 fs->super->s_hash_seed, &hash, 0);
7717 if (hash < dx_db->min_hash)
7718 dx_db->min_hash = hash;
7719 if (hash > dx_db->max_hash)
7720 dx_db->max_hash = hash;
7725 * If this is a directory, then mark its parent in its
7726 * dir_info structure. If the parent field is already
7727 * filled in, then this directory has more than one
7728 * hard link. We assume the first link is correct,
7729 * and ask the user if he/she wants to clear this one.
7731 if ((dot_state > 1) &&
7732 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7734 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
7736 cd->pctx.ino = dirent->inode;
7737 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
7738 goto abort_free_dict;
7740 if (subdir->parent) {
7741 cd->pctx.ino2 = subdir->parent;
7742 if (fix_problem(ctx, PR_2_LINK_DIR,
7750 subdir->parent = ino;
7755 } else if (dict_lookup(&de_dict, dirent)) {
7756 clear_problem_context(&pctx);
7758 pctx.dirent = dirent;
7759 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
7760 if (!ctx->dirs_to_hash)
7761 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
7762 if (ctx->dirs_to_hash)
7763 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
7766 dict_alloc_insert(&de_dict, dirent, dirent);
7768 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
7771 ctx->fs_links_count++;
7772 ctx->fs_total_count++;
7775 offset += dirent->rec_len;
7777 } while (offset < fs->blocksize);
7784 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
7785 db->blockcnt, dx_db->type,
7786 dx_db->min_hash, dx_db->max_hash);
7788 cd->pctx.dir = cd->pctx.ino;
7789 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
7790 (dx_db->type == DX_DIRBLOCK_NODE))
7791 parse_int_node(fs, db, cd, dx_dir, buf);
7793 #endif /* ENABLE_HTREE */
7794 if (offset != fs->blocksize) {
7795 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
7796 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
7797 dirent->rec_len = cd->pctx.num;
7802 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
7803 if (cd->pctx.errcode) {
7804 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
7806 goto abort_free_dict;
7808 ext2fs_mark_changed(fs);
7810 dict_free_nodes(&de_dict);
7813 dict_free_nodes(&de_dict);
7814 ctx->flags |= E2F_FLAG_ABORT;
7815 return DIRENT_ABORT;
7819 * This function is called to deallocate a block, and is an interator
7820 * functioned called by deallocate inode via ext2fs_iterate_block().
7822 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
7823 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
7824 blk_t ref_block FSCK_ATTR((unused)),
7825 int ref_offset FSCK_ATTR((unused)),
7828 e2fsck_t ctx = (e2fsck_t) priv_data;
7830 if (HOLE_BLKADDR(*block_nr))
7832 if ((*block_nr < fs->super->s_first_data_block) ||
7833 (*block_nr >= fs->super->s_blocks_count))
7835 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
7836 ext2fs_block_alloc_stats(fs, *block_nr, -1);
7841 * This fuction deallocates an inode
7843 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
7845 ext2_filsys fs = ctx->fs;
7846 struct ext2_inode inode;
7847 struct problem_context pctx;
7850 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
7851 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
7852 inode.i_links_count = 0;
7853 inode.i_dtime = time(0);
7854 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
7855 clear_problem_context(&pctx);
7859 * Fix up the bitmaps...
7861 e2fsck_read_bitmaps(ctx);
7862 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
7863 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
7864 if (ctx->inode_bad_map)
7865 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7866 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
7868 if (inode.i_file_acl &&
7869 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
7870 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
7871 block_buf, -1, &count);
7872 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
7877 pctx.blk = inode.i_file_acl;
7878 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
7879 ctx->flags |= E2F_FLAG_ABORT;
7883 ext2fs_unmark_block_bitmap(ctx->block_found_map,
7885 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
7887 inode.i_file_acl = 0;
7890 if (!ext2fs_inode_has_valid_blocks(&inode))
7893 if (LINUX_S_ISREG(inode.i_mode) &&
7894 (inode.i_size_high || inode.i_size & 0x80000000UL))
7897 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7898 deallocate_inode_block, ctx);
7900 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
7901 ctx->flags |= E2F_FLAG_ABORT;
7907 * This fuction clears the htree flag on an inode
7909 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
7911 struct ext2_inode inode;
7913 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
7914 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
7915 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
7916 if (ctx->dirs_to_hash)
7917 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
7921 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
7922 ext2_ino_t ino, char *buf)
7924 ext2_filsys fs = ctx->fs;
7925 struct ext2_inode inode;
7926 int inode_modified = 0;
7928 unsigned char *frag, *fsize;
7929 struct problem_context pctx;
7932 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
7934 clear_problem_context(&pctx);
7937 pctx.inode = &inode;
7939 if (inode.i_file_acl &&
7940 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
7941 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
7942 inode.i_file_acl = 0;
7943 #ifdef EXT2FS_ENABLE_SWAPFS
7945 * This is a special kludge to deal with long symlinks
7946 * on big endian systems. i_blocks had already been
7947 * decremented earlier in pass 1, but since i_file_acl
7948 * hadn't yet been cleared, ext2fs_read_inode()
7949 * assumed that the file was short symlink and would
7950 * not have byte swapped i_block[0]. Hence, we have
7951 * to byte-swap it here.
7953 if (LINUX_S_ISLNK(inode.i_mode) &&
7954 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
7955 (inode.i_blocks == fs->blocksize >> 9))
7956 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
7962 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
7963 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
7964 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
7965 !(LINUX_S_ISSOCK(inode.i_mode)))
7966 problem = PR_2_BAD_MODE;
7967 else if (LINUX_S_ISCHR(inode.i_mode)
7968 && !e2fsck_pass1_check_device_inode(fs, &inode))
7969 problem = PR_2_BAD_CHAR_DEV;
7970 else if (LINUX_S_ISBLK(inode.i_mode)
7971 && !e2fsck_pass1_check_device_inode(fs, &inode))
7972 problem = PR_2_BAD_BLOCK_DEV;
7973 else if (LINUX_S_ISFIFO(inode.i_mode)
7974 && !e2fsck_pass1_check_device_inode(fs, &inode))
7975 problem = PR_2_BAD_FIFO;
7976 else if (LINUX_S_ISSOCK(inode.i_mode)
7977 && !e2fsck_pass1_check_device_inode(fs, &inode))
7978 problem = PR_2_BAD_SOCKET;
7979 else if (LINUX_S_ISLNK(inode.i_mode)
7980 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
7981 problem = PR_2_INVALID_SYMLINK;
7985 if (fix_problem(ctx, problem, &pctx)) {
7986 deallocate_inode(ctx, ino, 0);
7987 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7995 if (inode.i_faddr) {
7996 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
8003 switch (fs->super->s_creator_os) {
8005 frag = &inode.osd2.linux2.l_i_frag;
8006 fsize = &inode.osd2.linux2.l_i_fsize;
8009 frag = &inode.osd2.hurd2.h_i_frag;
8010 fsize = &inode.osd2.hurd2.h_i_fsize;
8013 frag = &inode.osd2.masix2.m_i_frag;
8014 fsize = &inode.osd2.masix2.m_i_fsize;
8019 if (frag && *frag) {
8021 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
8028 if (fsize && *fsize) {
8030 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
8038 if (inode.i_file_acl &&
8039 ((inode.i_file_acl < fs->super->s_first_data_block) ||
8040 (inode.i_file_acl >= fs->super->s_blocks_count))) {
8041 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
8042 inode.i_file_acl = 0;
8047 if (inode.i_dir_acl &&
8048 LINUX_S_ISDIR(inode.i_mode)) {
8049 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
8050 inode.i_dir_acl = 0;
8057 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
8059 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8065 * allocate_dir_block --- this function allocates a new directory
8066 * block for a particular inode; this is done if a directory has
8067 * a "hole" in it, or if a directory has a illegal block number
8068 * that was zeroed out and now needs to be replaced.
8070 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
8071 struct problem_context *pctx)
8073 ext2_filsys fs = ctx->fs;
8076 struct ext2_inode inode;
8078 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
8082 * Read the inode and block bitmaps in; we'll be messing with
8085 e2fsck_read_bitmaps(ctx);
8088 * First, find a free block
8090 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8091 if (pctx->errcode) {
8092 pctx->str = "ext2fs_new_block";
8093 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8096 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8097 ext2fs_mark_block_bitmap(fs->block_map, blk);
8098 ext2fs_mark_bb_dirty(fs);
8101 * Now let's create the actual data block for the inode
8104 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
8106 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
8107 EXT2_ROOT_INO, &block);
8109 if (pctx->errcode) {
8110 pctx->str = "ext2fs_new_dir_block";
8111 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8115 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
8116 ext2fs_free_mem(&block);
8117 if (pctx->errcode) {
8118 pctx->str = "ext2fs_write_dir_block";
8119 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8124 * Update the inode block count
8126 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
8127 inode.i_blocks += fs->blocksize / 512;
8128 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
8129 inode.i_size = (db->blockcnt+1) * fs->blocksize;
8130 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
8133 * Finally, update the block pointers for the inode
8136 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
8137 0, update_dir_block, db);
8138 if (pctx->errcode) {
8139 pctx->str = "ext2fs_block_iterate";
8140 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8148 * This is a helper function for allocate_dir_block().
8150 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
8152 e2_blkcnt_t blockcnt,
8153 blk_t ref_block FSCK_ATTR((unused)),
8154 int ref_offset FSCK_ATTR((unused)),
8157 struct ext2_db_entry *db;
8159 db = (struct ext2_db_entry *) priv_data;
8160 if (db->blockcnt == (int) blockcnt) {
8161 *block_nr = db->blk;
8162 return BLOCK_CHANGED;
8168 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
8170 * Pass #3 assures that all directories are connected to the
8171 * filesystem tree, using the following algorithm:
8173 * First, the root directory is checked to make sure it exists; if
8174 * not, e2fsck will offer to create a new one. It is then marked as
8177 * Then, pass3 interates over all directory inodes; for each directory
8178 * it attempts to trace up the filesystem tree, using dirinfo.parent
8179 * until it reaches a directory which has been marked "done". If it
8180 * can not do so, then the directory must be disconnected, and e2fsck
8181 * will offer to reconnect it to /lost+found. While it is chasing
8182 * parent pointers up the filesystem tree, if pass3 sees a directory
8183 * twice, then it has detected a filesystem loop, and it will again
8184 * offer to reconnect the directory to /lost+found in to break the
8187 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
8188 * reconnect inodes to /lost+found; this subroutine is also used by
8189 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
8190 * is responsible for creating /lost+found if it does not exist.
8192 * Pass 3 frees the following data structures:
8193 * - The dirinfo directory information cache.
8196 static void check_root(e2fsck_t ctx);
8197 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8198 struct problem_context *pctx);
8199 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
8201 static ext2fs_inode_bitmap inode_loop_detect;
8202 static ext2fs_inode_bitmap inode_done_map;
8204 static void e2fsck_pass3(e2fsck_t ctx)
8206 ext2_filsys fs = ctx->fs;
8208 #ifdef RESOURCE_TRACK
8209 struct resource_track rtrack;
8211 struct problem_context pctx;
8212 struct dir_info *dir;
8213 unsigned long maxdirs, count;
8215 #ifdef RESOURCE_TRACK
8216 init_resource_track(&rtrack);
8219 clear_problem_context(&pctx);
8222 mtrace_print("Pass 3");
8225 if (!(ctx->options & E2F_OPT_PREEN))
8226 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
8229 * Allocate some bitmaps to do loop detection.
8231 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
8235 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
8236 ctx->flags |= E2F_FLAG_ABORT;
8239 #ifdef RESOURCE_TRACK
8240 if (ctx->options & E2F_OPT_TIME) {
8241 e2fsck_clear_progbar(ctx);
8242 print_resource_track(_("Peak memory"), &ctx->global_rtrack);
8247 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8250 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
8252 maxdirs = e2fsck_get_num_dirinfo(ctx);
8256 if ((ctx->progress)(ctx, 3, 0, maxdirs))
8259 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
8260 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8262 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
8264 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
8265 if (check_directory(ctx, dir, &pctx))
8270 * Force the creation of /lost+found if not present
8272 if ((ctx->flags & E2F_OPT_READONLY) == 0)
8273 e2fsck_get_lost_and_found(ctx, 1);
8276 * If there are any directories that need to be indexed or
8277 * optimized, do it here.
8279 e2fsck_rehash_directories(ctx);
8282 e2fsck_free_dir_info(ctx);
8283 ext2fs_free_inode_bitmap(inode_loop_detect);
8284 inode_loop_detect = 0;
8285 ext2fs_free_inode_bitmap(inode_done_map);
8288 #ifdef RESOURCE_TRACK
8289 if (ctx->options & E2F_OPT_TIME2) {
8290 e2fsck_clear_progbar(ctx);
8291 print_resource_track(_("Pass 3"), &rtrack);
8297 * This makes sure the root inode is present; if not, we ask if the
8298 * user wants us to create it. Not creating it is a fatal error.
8300 static void check_root(e2fsck_t ctx)
8302 ext2_filsys fs = ctx->fs;
8304 struct ext2_inode inode;
8306 struct problem_context pctx;
8308 clear_problem_context(&pctx);
8310 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
8312 * If the root inode is not a directory, die here. The
8313 * user must have answered 'no' in pass1 when we
8314 * offered to clear it.
8316 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8318 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
8319 ctx->flags |= E2F_FLAG_ABORT;
8324 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
8325 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
8326 ctx->flags |= E2F_FLAG_ABORT;
8330 e2fsck_read_bitmaps(ctx);
8333 * First, find a free block
8335 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8337 pctx.str = "ext2fs_new_block";
8338 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8339 ctx->flags |= E2F_FLAG_ABORT;
8342 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8343 ext2fs_mark_block_bitmap(fs->block_map, blk);
8344 ext2fs_mark_bb_dirty(fs);
8347 * Now let's create the actual data block for the inode
8349 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
8352 pctx.str = "ext2fs_new_dir_block";
8353 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8354 ctx->flags |= E2F_FLAG_ABORT;
8358 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
8360 pctx.str = "ext2fs_write_dir_block";
8361 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8362 ctx->flags |= E2F_FLAG_ABORT;
8365 ext2fs_free_mem(&block);
8368 * Set up the inode structure
8370 memset(&inode, 0, sizeof(inode));
8371 inode.i_mode = 040755;
8372 inode.i_size = fs->blocksize;
8373 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8374 inode.i_links_count = 2;
8375 inode.i_blocks = fs->blocksize / 512;
8376 inode.i_block[0] = blk;
8379 * Write out the inode.
8381 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
8383 pctx.str = "ext2fs_write_inode";
8384 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8385 ctx->flags |= E2F_FLAG_ABORT;
8390 * Miscellaneous bookkeeping...
8392 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
8393 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
8394 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
8396 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
8397 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
8398 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
8399 ext2fs_mark_ib_dirty(fs);
8403 * This subroutine is responsible for making sure that a particular
8404 * directory is connected to the root; if it isn't we trace it up as
8405 * far as we can go, and then offer to connect the resulting parent to
8406 * the lost+found. We have to do loop detection; if we ever discover
8407 * a loop, we treat that as a disconnected directory and offer to
8408 * reparent it to lost+found.
8410 * However, loop detection is expensive, because for very large
8411 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
8412 * is non-trivial. Loops in filesystems are also a rare error case,
8413 * and we shouldn't optimize for error cases. So we try two passes of
8414 * the algorithm. The first time, we ignore loop detection and merely
8415 * increment a counter; if the counter exceeds some extreme threshold,
8416 * then we try again with the loop detection bitmap enabled.
8418 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8419 struct problem_context *pctx)
8421 ext2_filsys fs = ctx->fs;
8422 struct dir_info *p = dir;
8423 int loop_pass = 0, parent_count = 0;
8430 * Mark this inode as being "done"; by the time we
8431 * return from this function, the inode we either be
8432 * verified as being connected to the directory tree,
8433 * or we will have offered to reconnect this to
8436 * If it was marked done already, then we've reached a
8437 * parent we've already checked.
8439 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
8443 * If this directory doesn't have a parent, or we've
8444 * seen the parent once already, then offer to
8445 * reparent it to lost+found
8449 (ext2fs_test_inode_bitmap(inode_loop_detect,
8452 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
8453 if (e2fsck_reconnect_file(ctx, pctx->ino))
8454 ext2fs_unmark_valid(fs);
8456 p = e2fsck_get_dir_info(ctx, pctx->ino);
8457 p->parent = ctx->lost_and_found;
8458 fix_dotdot(ctx, p, ctx->lost_and_found);
8463 p = e2fsck_get_dir_info(ctx, p->parent);
8465 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
8469 ext2fs_mark_inode_bitmap(inode_loop_detect,
8471 } else if (parent_count++ > 2048) {
8473 * If we've run into a path depth that's
8474 * greater than 2048, try again with the inode
8475 * loop bitmap turned on and start from the
8479 if (inode_loop_detect)
8480 ext2fs_clear_inode_bitmap(inode_loop_detect);
8482 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
8483 if (pctx->errcode) {
8486 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
8487 ctx->flags |= E2F_FLAG_ABORT;
8496 * Make sure that .. and the parent directory are the same;
8497 * offer to fix it if not.
8499 if (dir->parent != dir->dotdot) {
8500 pctx->ino = dir->ino;
8501 pctx->ino2 = dir->dotdot;
8502 pctx->dir = dir->parent;
8503 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
8504 fix_dotdot(ctx, dir, dir->parent);
8510 * This routine gets the lost_and_found inode, making it a directory
8513 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
8515 ext2_filsys fs = ctx->fs;
8519 struct ext2_inode inode;
8521 static const char name[] = "lost+found";
8522 struct problem_context pctx;
8523 struct dir_info *dirinfo;
8525 if (ctx->lost_and_found)
8526 return ctx->lost_and_found;
8528 clear_problem_context(&pctx);
8530 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
8531 sizeof(name)-1, 0, &ino);
8535 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
8536 ctx->lost_and_found = ino;
8540 /* Lost+found isn't a directory! */
8544 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
8547 /* OK, unlink the old /lost+found file. */
8548 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
8550 pctx.str = "ext2fs_unlink";
8551 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8554 dirinfo = e2fsck_get_dir_info(ctx, ino);
8556 dirinfo->parent = 0;
8557 e2fsck_adjust_inode_count(ctx, ino, -1);
8558 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
8559 pctx.errcode = retval;
8560 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
8562 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
8566 * Read the inode and block bitmaps in; we'll be messing with
8569 e2fsck_read_bitmaps(ctx);
8572 * First, find a free block
8574 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8576 pctx.errcode = retval;
8577 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
8580 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8581 ext2fs_block_alloc_stats(fs, blk, +1);
8584 * Next find a free inode.
8586 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
8587 ctx->inode_used_map, &ino);
8589 pctx.errcode = retval;
8590 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
8593 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
8594 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
8595 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
8598 * Now let's create the actual data block for the inode
8600 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
8602 pctx.errcode = retval;
8603 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
8607 retval = ext2fs_write_dir_block(fs, blk, block);
8608 ext2fs_free_mem(&block);
8610 pctx.errcode = retval;
8611 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
8616 * Set up the inode structure
8618 memset(&inode, 0, sizeof(inode));
8619 inode.i_mode = 040700;
8620 inode.i_size = fs->blocksize;
8621 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8622 inode.i_links_count = 2;
8623 inode.i_blocks = fs->blocksize / 512;
8624 inode.i_block[0] = blk;
8627 * Next, write out the inode.
8629 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
8631 pctx.str = "ext2fs_write_inode";
8632 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8636 * Finally, create the directory link
8638 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
8640 pctx.str = "ext2fs_link";
8641 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8646 * Miscellaneous bookkeeping that needs to be kept straight.
8648 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
8649 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
8650 ext2fs_icount_store(ctx->inode_count, ino, 2);
8651 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
8652 ctx->lost_and_found = ino;
8654 printf("/lost+found created; inode #%lu\n", ino);
8660 * This routine will connect a file to lost+found
8662 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
8664 ext2_filsys fs = ctx->fs;
8667 struct problem_context pctx;
8668 struct ext2_inode inode;
8671 clear_problem_context(&pctx);
8674 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
8675 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
8676 ctx->bad_lost_and_found++;
8678 if (ctx->bad_lost_and_found) {
8679 fix_problem(ctx, PR_3_NO_LPF, &pctx);
8683 sprintf(name, "#%u", ino);
8684 if (ext2fs_read_inode(fs, ino, &inode) == 0)
8685 file_type = ext2_file_type(inode.i_mode);
8686 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
8687 if (retval == EXT2_ET_DIR_NO_SPACE) {
8688 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
8690 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
8693 pctx.errcode = retval;
8694 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
8697 retval = ext2fs_link(fs, ctx->lost_and_found, name,
8701 pctx.errcode = retval;
8702 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
8705 e2fsck_adjust_inode_count(ctx, ino, 1);
8711 * Utility routine to adjust the inode counts on an inode.
8713 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
8715 ext2_filsys fs = ctx->fs;
8717 struct ext2_inode inode;
8722 retval = ext2fs_read_inode(fs, ino, &inode);
8727 printf("Adjusting link count for inode %lu by %d (from %d)\n", ino, adj,
8728 inode.i_links_count);
8732 ext2fs_icount_increment(ctx->inode_count, ino, 0);
8733 if (inode.i_links_count == (__u16) ~0)
8735 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
8736 inode.i_links_count++;
8737 } else if (adj == -1) {
8738 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
8739 if (inode.i_links_count == 0)
8741 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
8742 inode.i_links_count--;
8745 retval = ext2fs_write_inode(fs, ino, &inode);
8753 * Fix parent --- this routine fixes up the parent of a directory.
8755 struct fix_dotdot_struct {
8762 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
8763 int offset FSCK_ATTR((unused)),
8764 int blocksize FSCK_ATTR((unused)),
8765 char *buf FSCK_ATTR((unused)),
8768 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
8770 struct problem_context pctx;
8772 if ((dirent->name_len & 0xFF) != 2)
8774 if (strncmp(dirent->name, "..", 2))
8777 clear_problem_context(&pctx);
8779 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
8781 pctx.errcode = retval;
8782 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
8784 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
8786 pctx.errcode = retval;
8787 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
8789 dirent->inode = fp->parent;
8792 return DIRENT_ABORT | DIRENT_CHANGED;
8795 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
8797 ext2_filsys fs = ctx->fs;
8799 struct fix_dotdot_struct fp;
8800 struct problem_context pctx;
8808 printf("Fixing '..' of inode %lu to be %lu...\n", dir->ino, parent);
8811 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
8812 0, fix_dotdot_proc, &fp);
8813 if (retval || !fp.done) {
8814 clear_problem_context(&pctx);
8815 pctx.ino = dir->ino;
8816 pctx.errcode = retval;
8817 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
8818 PR_3_FIX_PARENT_NOFIND, &pctx);
8819 ext2fs_unmark_valid(fs);
8821 dir->dotdot = parent;
8827 * These routines are responsible for expanding a /lost+found if it is
8831 struct expand_dir_struct {
8833 int guaranteed_size;
8840 static int expand_dir_proc(ext2_filsys fs,
8842 e2_blkcnt_t blockcnt,
8843 blk_t ref_block FSCK_ATTR((unused)),
8844 int ref_offset FSCK_ATTR((unused)),
8847 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
8849 static blk_t last_blk = 0;
8856 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
8860 es->last_block = blockcnt;
8862 last_blk = *blocknr;
8865 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
8872 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
8878 retval = ext2fs_write_dir_block(fs, new_blk, block);
8880 retval = ext2fs_get_mem(fs->blocksize, &block);
8885 memset(block, 0, fs->blocksize);
8886 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
8892 ext2fs_free_mem(&block);
8894 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
8895 ext2fs_block_alloc_stats(fs, new_blk, +1);
8899 return (BLOCK_CHANGED | BLOCK_ABORT);
8901 return BLOCK_CHANGED;
8904 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
8905 int num, int guaranteed_size)
8907 ext2_filsys fs = ctx->fs;
8909 struct expand_dir_struct es;
8910 struct ext2_inode inode;
8912 if (!(fs->flags & EXT2_FLAG_RW))
8913 return EXT2_ET_RO_FILSYS;
8916 * Read the inode and block bitmaps in; we'll be messing with
8919 e2fsck_read_bitmaps(ctx);
8921 retval = ext2fs_check_directory(fs, dir);
8926 es.guaranteed_size = guaranteed_size;
8932 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
8933 0, expand_dir_proc, &es);
8939 * Update the size and block count fields in the inode.
8941 retval = ext2fs_read_inode(fs, dir, &inode);
8945 inode.i_size = (es.last_block + 1) * fs->blocksize;
8946 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
8948 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
8954 * pass4.c -- pass #4 of e2fsck: Check reference counts
8956 * Pass 4 frees the following data structures:
8957 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
8958 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
8962 * This routine is called when an inode is not connected to the
8965 * This subroutine returns 1 then the caller shouldn't bother with the
8966 * rest of the pass 4 tests.
8968 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
8970 ext2_filsys fs = ctx->fs;
8971 struct ext2_inode inode;
8972 struct problem_context pctx;
8974 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
8975 clear_problem_context(&pctx);
8977 pctx.inode = &inode;
8980 * Offer to delete any zero-length files that does not have
8981 * blocks. If there is an EA block, it might have useful
8982 * information, so we won't prompt to delete it, but let it be
8983 * reconnected to lost+found.
8985 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
8986 LINUX_S_ISDIR(inode.i_mode))) {
8987 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
8988 ext2fs_icount_store(ctx->inode_link_info, i, 0);
8989 inode.i_links_count = 0;
8990 inode.i_dtime = time(0);
8991 e2fsck_write_inode(ctx, i, &inode,
8992 "disconnect_inode");
8994 * Fix up the bitmaps...
8996 e2fsck_read_bitmaps(ctx);
8997 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
8998 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
8999 ext2fs_inode_alloc_stats2(fs, i, -1,
9000 LINUX_S_ISDIR(inode.i_mode));
9006 * Prompt to reconnect.
9008 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
9009 if (e2fsck_reconnect_file(ctx, i))
9010 ext2fs_unmark_valid(fs);
9013 * If we don't attach the inode, then skip the
9014 * i_links_test since there's no point in trying to
9015 * force i_links_count to zero.
9017 ext2fs_unmark_valid(fs);
9024 static void e2fsck_pass4(e2fsck_t ctx)
9026 ext2_filsys fs = ctx->fs;
9028 struct ext2_inode inode;
9029 #ifdef RESOURCE_TRACK
9030 struct resource_track rtrack;
9032 struct problem_context pctx;
9033 __u16 link_count, link_counted;
9035 int group, maxgroup;
9037 #ifdef RESOURCE_TRACK
9038 init_resource_track(&rtrack);
9042 mtrace_print("Pass 4");
9045 clear_problem_context(&pctx);
9047 if (!(ctx->options & E2F_OPT_PREEN))
9048 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
9051 maxgroup = fs->group_desc_count;
9053 if ((ctx->progress)(ctx, 4, 0, maxgroup))
9056 for (i=1; i <= fs->super->s_inodes_count; i++) {
9057 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9059 if ((i % fs->super->s_inodes_per_group) == 0) {
9062 if ((ctx->progress)(ctx, 4, group, maxgroup))
9065 if (i == EXT2_BAD_INO ||
9066 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
9068 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
9069 (ctx->inode_imagic_map &&
9070 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
9071 (ctx->inode_bb_map &&
9072 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
9074 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
9075 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
9076 if (link_counted == 0) {
9078 buf = e2fsck_allocate_memory(ctx,
9079 fs->blocksize, "bad_inode buffer");
9080 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
9082 if (disconnect_inode(ctx, i))
9084 ext2fs_icount_fetch(ctx->inode_link_info, i,
9086 ext2fs_icount_fetch(ctx->inode_count, i,
9089 if (link_counted != link_count) {
9090 e2fsck_read_inode(ctx, i, &inode, "pass4");
9092 pctx.inode = &inode;
9093 if (link_count != inode.i_links_count) {
9094 pctx.num = link_count;
9096 PR_4_INCONSISTENT_COUNT, &pctx);
9098 pctx.num = link_counted;
9099 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
9100 inode.i_links_count = link_counted;
9101 e2fsck_write_inode(ctx, i, &inode, "pass4");
9105 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
9106 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
9107 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
9108 ctx->inode_bb_map = 0;
9109 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
9110 ctx->inode_imagic_map = 0;
9111 ext2fs_free_mem(&buf);
9112 #ifdef RESOURCE_TRACK
9113 if (ctx->options & E2F_OPT_TIME2) {
9114 e2fsck_clear_progbar(ctx);
9115 print_resource_track(_("Pass 4"), &rtrack);
9121 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
9124 #define NO_BLK ((blk_t) -1)
9126 static void print_bitmap_problem(e2fsck_t ctx, int problem,
9127 struct problem_context *pctx)
9130 case PR_5_BLOCK_UNUSED:
9131 if (pctx->blk == pctx->blk2)
9134 problem = PR_5_BLOCK_RANGE_UNUSED;
9136 case PR_5_BLOCK_USED:
9137 if (pctx->blk == pctx->blk2)
9140 problem = PR_5_BLOCK_RANGE_USED;
9142 case PR_5_INODE_UNUSED:
9143 if (pctx->ino == pctx->ino2)
9146 problem = PR_5_INODE_RANGE_UNUSED;
9148 case PR_5_INODE_USED:
9149 if (pctx->ino == pctx->ino2)
9152 problem = PR_5_INODE_RANGE_USED;
9155 fix_problem(ctx, problem, pctx);
9156 pctx->blk = pctx->blk2 = NO_BLK;
9157 pctx->ino = pctx->ino2 = 0;
9160 static void check_block_bitmaps(e2fsck_t ctx)
9162 ext2_filsys fs = ctx->fs;
9166 unsigned int blocks = 0;
9167 unsigned int free_blocks = 0;
9170 struct problem_context pctx;
9171 int problem, save_problem, fixit, had_problem;
9174 clear_problem_context(&pctx);
9175 free_array = (int *) e2fsck_allocate_memory(ctx,
9176 fs->group_desc_count * sizeof(int), "free block count array");
9178 if ((fs->super->s_first_data_block <
9179 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
9180 (fs->super->s_blocks_count-1 >
9181 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
9183 pctx.blk = fs->super->s_first_data_block;
9184 pctx.blk2 = fs->super->s_blocks_count -1;
9185 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
9186 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
9187 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9189 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9193 if ((fs->super->s_first_data_block <
9194 ext2fs_get_block_bitmap_start(fs->block_map)) ||
9195 (fs->super->s_blocks_count-1 >
9196 ext2fs_get_block_bitmap_end(fs->block_map))) {
9198 pctx.blk = fs->super->s_first_data_block;
9199 pctx.blk2 = fs->super->s_blocks_count -1;
9200 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
9201 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
9202 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9204 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9211 pctx.blk = pctx.blk2 = NO_BLK;
9212 for (i = fs->super->s_first_data_block;
9213 i < fs->super->s_blocks_count;
9215 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
9216 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
9218 if (actual == bitmap)
9221 if (!actual && bitmap) {
9223 * Block not used, but marked in use in the bitmap.
9225 problem = PR_5_BLOCK_UNUSED;
9228 * Block used, but not marked in use in the bitmap.
9230 problem = PR_5_BLOCK_USED;
9232 if (pctx.blk == NO_BLK) {
9233 pctx.blk = pctx.blk2 = i;
9234 save_problem = problem;
9236 if ((problem == save_problem) &&
9240 print_bitmap_problem(ctx, save_problem, &pctx);
9241 pctx.blk = pctx.blk2 = i;
9242 save_problem = problem;
9245 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9254 if ((blocks == fs->super->s_blocks_per_group) ||
9255 (i == fs->super->s_blocks_count-1)) {
9256 free_array[group] = group_free;
9261 if ((ctx->progress)(ctx, 5, group,
9262 fs->group_desc_count*2))
9266 if (pctx.blk != NO_BLK)
9267 print_bitmap_problem(ctx, save_problem, &pctx);
9269 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
9272 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9275 ext2fs_free_block_bitmap(fs->block_map);
9276 retval = ext2fs_copy_bitmap(ctx->block_found_map,
9279 clear_problem_context(&pctx);
9280 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
9281 ctx->flags |= E2F_FLAG_ABORT;
9284 ext2fs_set_bitmap_padding(fs->block_map);
9285 ext2fs_mark_bb_dirty(fs);
9287 /* Redo the counts */
9288 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
9289 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9291 } else if (fixit == 0)
9292 ext2fs_unmark_valid(fs);
9294 for (i = 0; i < fs->group_desc_count; i++) {
9295 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
9297 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
9298 pctx.blk2 = free_array[i];
9300 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
9302 fs->group_desc[i].bg_free_blocks_count =
9304 ext2fs_mark_super_dirty(fs);
9306 ext2fs_unmark_valid(fs);
9309 if (free_blocks != fs->super->s_free_blocks_count) {
9311 pctx.blk = fs->super->s_free_blocks_count;
9312 pctx.blk2 = free_blocks;
9314 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
9315 fs->super->s_free_blocks_count = free_blocks;
9316 ext2fs_mark_super_dirty(fs);
9318 ext2fs_unmark_valid(fs);
9320 ext2fs_free_mem(&free_array);
9323 static void check_inode_bitmaps(e2fsck_t ctx)
9325 ext2_filsys fs = ctx->fs;
9327 unsigned int free_inodes = 0;
9331 unsigned int inodes = 0;
9336 struct problem_context pctx;
9337 int problem, save_problem, fixit, had_problem;
9339 clear_problem_context(&pctx);
9340 free_array = (int *) e2fsck_allocate_memory(ctx,
9341 fs->group_desc_count * sizeof(int), "free inode count array");
9343 dir_array = (int *) e2fsck_allocate_memory(ctx,
9344 fs->group_desc_count * sizeof(int), "directory count array");
9346 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
9347 (fs->super->s_inodes_count >
9348 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
9351 pctx.blk2 = fs->super->s_inodes_count;
9352 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
9353 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
9354 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9356 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9359 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
9360 (fs->super->s_inodes_count >
9361 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
9364 pctx.blk2 = fs->super->s_inodes_count;
9365 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
9366 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
9367 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9369 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9376 pctx.ino = pctx.ino2 = 0;
9377 for (i = 1; i <= fs->super->s_inodes_count; i++) {
9378 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
9379 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
9381 if (actual == bitmap)
9384 if (!actual && bitmap) {
9386 * Inode wasn't used, but marked in bitmap
9388 problem = PR_5_INODE_UNUSED;
9389 } else /* if (actual && !bitmap) */ {
9391 * Inode used, but not in bitmap
9393 problem = PR_5_INODE_USED;
9395 if (pctx.ino == 0) {
9396 pctx.ino = pctx.ino2 = i;
9397 save_problem = problem;
9399 if ((problem == save_problem) &&
9403 print_bitmap_problem(ctx, save_problem, &pctx);
9404 pctx.ino = pctx.ino2 = i;
9405 save_problem = problem;
9408 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9416 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
9420 if ((inodes == fs->super->s_inodes_per_group) ||
9421 (i == fs->super->s_inodes_count)) {
9422 free_array[group] = group_free;
9423 dir_array[group] = dirs_count;
9429 if ((ctx->progress)(ctx, 5,
9430 group + fs->group_desc_count,
9431 fs->group_desc_count*2))
9436 print_bitmap_problem(ctx, save_problem, &pctx);
9439 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
9442 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9445 ext2fs_free_inode_bitmap(fs->inode_map);
9446 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
9449 clear_problem_context(&pctx);
9450 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
9451 ctx->flags |= E2F_FLAG_ABORT;
9454 ext2fs_set_bitmap_padding(fs->inode_map);
9455 ext2fs_mark_ib_dirty(fs);
9458 inodes = 0; free_inodes = 0; group_free = 0;
9459 dirs_count = 0; group = 0;
9460 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9461 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
9463 } else if (fixit == 0)
9464 ext2fs_unmark_valid(fs);
9466 for (i = 0; i < fs->group_desc_count; i++) {
9467 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
9469 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
9470 pctx.ino2 = free_array[i];
9471 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
9473 fs->group_desc[i].bg_free_inodes_count =
9475 ext2fs_mark_super_dirty(fs);
9477 ext2fs_unmark_valid(fs);
9479 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
9481 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
9482 pctx.ino2 = dir_array[i];
9484 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
9486 fs->group_desc[i].bg_used_dirs_count =
9488 ext2fs_mark_super_dirty(fs);
9490 ext2fs_unmark_valid(fs);
9493 if (free_inodes != fs->super->s_free_inodes_count) {
9495 pctx.ino = fs->super->s_free_inodes_count;
9496 pctx.ino2 = free_inodes;
9498 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
9499 fs->super->s_free_inodes_count = free_inodes;
9500 ext2fs_mark_super_dirty(fs);
9502 ext2fs_unmark_valid(fs);
9504 ext2fs_free_mem(&free_array);
9505 ext2fs_free_mem(&dir_array);
9508 static void check_inode_end(e2fsck_t ctx)
9510 ext2_filsys fs = ctx->fs;
9511 ext2_ino_t end, save_inodes_count, i;
9512 struct problem_context pctx;
9514 clear_problem_context(&pctx);
9516 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
9517 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
9518 &save_inodes_count);
9521 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9522 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9525 if (save_inodes_count == end)
9528 for (i = save_inodes_count + 1; i <= end; i++) {
9529 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
9530 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
9531 for (i = save_inodes_count + 1; i <= end; i++)
9532 ext2fs_mark_inode_bitmap(fs->inode_map,
9534 ext2fs_mark_ib_dirty(fs);
9536 ext2fs_unmark_valid(fs);
9541 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
9542 save_inodes_count, 0);
9545 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9546 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9551 static void check_block_end(e2fsck_t ctx)
9553 ext2_filsys fs = ctx->fs;
9554 blk_t end, save_blocks_count, i;
9555 struct problem_context pctx;
9557 clear_problem_context(&pctx);
9559 end = fs->block_map->start +
9560 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
9561 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
9562 &save_blocks_count);
9565 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9566 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9569 if (save_blocks_count == end)
9572 for (i = save_blocks_count + 1; i <= end; i++) {
9573 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
9574 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
9575 for (i = save_blocks_count + 1; i <= end; i++)
9576 ext2fs_mark_block_bitmap(fs->block_map,
9578 ext2fs_mark_bb_dirty(fs);
9580 ext2fs_unmark_valid(fs);
9585 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
9586 save_blocks_count, 0);
9589 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9590 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9595 static void e2fsck_pass5(e2fsck_t ctx)
9597 #ifdef RESOURCE_TRACK
9598 struct resource_track rtrack;
9600 struct problem_context pctx;
9603 mtrace_print("Pass 5");
9606 #ifdef RESOURCE_TRACK
9607 init_resource_track(&rtrack);
9610 clear_problem_context(&pctx);
9612 if (!(ctx->options & E2F_OPT_PREEN))
9613 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
9616 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
9619 e2fsck_read_bitmaps(ctx);
9621 check_block_bitmaps(ctx);
9622 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9624 check_inode_bitmaps(ctx);
9625 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9627 check_inode_end(ctx);
9628 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9630 check_block_end(ctx);
9631 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9634 ext2fs_free_inode_bitmap(ctx->inode_used_map);
9635 ctx->inode_used_map = 0;
9636 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
9637 ctx->inode_dir_map = 0;
9638 ext2fs_free_block_bitmap(ctx->block_found_map);
9639 ctx->block_found_map = 0;
9641 #ifdef RESOURCE_TRACK
9642 if (ctx->options & E2F_OPT_TIME2) {
9643 e2fsck_clear_progbar(ctx);
9644 print_resource_track(_("Pass 5"), &rtrack);
9650 * problem.c --- report filesystem problems to the user
9653 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
9654 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
9655 #define PR_NO_DEFAULT 0x000004 /* Default to no */
9656 #define PR_MSG_ONLY 0x000008 /* Print message only */
9658 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
9660 #define PR_FATAL 0x001000 /* Fatal error */
9661 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
9663 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
9664 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
9665 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
9666 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
9667 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
9670 #define PROMPT_NONE 0
9671 #define PROMPT_FIX 1
9672 #define PROMPT_CLEAR 2
9673 #define PROMPT_RELOCATE 3
9674 #define PROMPT_ALLOCATE 4
9675 #define PROMPT_EXPAND 5
9676 #define PROMPT_CONNECT 6
9677 #define PROMPT_CREATE 7
9678 #define PROMPT_SALVAGE 8
9679 #define PROMPT_TRUNCATE 9
9680 #define PROMPT_CLEAR_INODE 10
9681 #define PROMPT_ABORT 11
9682 #define PROMPT_SPLIT 12
9683 #define PROMPT_CONTINUE 13
9684 #define PROMPT_CLONE 14
9685 #define PROMPT_DELETE 15
9686 #define PROMPT_SUPPRESS 16
9687 #define PROMPT_UNLINK 17
9688 #define PROMPT_CLEAR_HTREE 18
9689 #define PROMPT_RECREATE 19
9690 #define PROMPT_NULL 20
9692 struct e2fsck_problem {
9694 const char * e2p_description;
9697 problem_t second_code;
9700 struct latch_descr {
9703 problem_t end_message;
9708 * These are the prompts which are used to ask the user if they want
9711 static const char * const prompt[] = {
9712 N_("(no prompt)"), /* 0 */
9714 N_("Clear"), /* 2 */
9715 N_("Relocate"), /* 3 */
9716 N_("Allocate"), /* 4 */
9717 N_("Expand"), /* 5 */
9718 N_("Connect to /lost+found"), /* 6 */
9719 N_("Create"), /* 7 */
9720 N_("Salvage"), /* 8 */
9721 N_("Truncate"), /* 9 */
9722 N_("Clear inode"), /* 10 */
9723 N_("Abort"), /* 11 */
9724 N_("Split"), /* 12 */
9725 N_("Continue"), /* 13 */
9726 N_("Clone multiply-claimed blocks"), /* 14 */
9727 N_("Delete file"), /* 15 */
9728 N_("Suppress messages"),/* 16 */
9729 N_("Unlink"), /* 17 */
9730 N_("Clear HTree index"),/* 18 */
9731 N_("Recreate"), /* 19 */
9736 * These messages are printed when we are preen mode and we will be
9737 * automatically fixing the problem.
9739 static const char * const preen_msg[] = {
9740 N_("(NONE)"), /* 0 */
9741 N_("FIXED"), /* 1 */
9742 N_("CLEARED"), /* 2 */
9743 N_("RELOCATED"), /* 3 */
9744 N_("ALLOCATED"), /* 4 */
9745 N_("EXPANDED"), /* 5 */
9746 N_("RECONNECTED"), /* 6 */
9747 N_("CREATED"), /* 7 */
9748 N_("SALVAGED"), /* 8 */
9749 N_("TRUNCATED"), /* 9 */
9750 N_("INODE CLEARED"), /* 10 */
9751 N_("ABORTED"), /* 11 */
9752 N_("SPLIT"), /* 12 */
9753 N_("CONTINUING"), /* 13 */
9754 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
9755 N_("FILE DELETED"), /* 15 */
9756 N_("SUPPRESSED"), /* 16 */
9757 N_("UNLINKED"), /* 17 */
9758 N_("HTREE INDEX CLEARED"),/* 18 */
9759 N_("WILL RECREATE"), /* 19 */
9763 static const struct e2fsck_problem problem_table[] = {
9765 /* Pre-Pass 1 errors */
9767 /* Block bitmap not in group */
9768 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
9769 PROMPT_RELOCATE, PR_LATCH_RELOC },
9771 /* Inode bitmap not in group */
9772 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
9773 PROMPT_RELOCATE, PR_LATCH_RELOC },
9775 /* Inode table not in group */
9776 { PR_0_ITABLE_NOT_GROUP,
9777 N_("@i table for @g %g is not in @g. (@b %b)\n"
9778 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
9779 PROMPT_RELOCATE, PR_LATCH_RELOC },
9781 /* Superblock corrupt */
9783 N_("\nThe @S could not be read or does not describe a correct ext2\n"
9784 "@f. If the @v is valid and it really contains an ext2\n"
9785 "@f (and not swap or ufs or something else), then the @S\n"
9786 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
9787 " e2fsck -b %S <@v>\n\n"),
9788 PROMPT_NONE, PR_FATAL },
9790 /* Filesystem size is wrong */
9791 { PR_0_FS_SIZE_WRONG,
9792 N_("The @f size (according to the @S) is %b @bs\n"
9793 "The physical size of the @v is %c @bs\n"
9794 "Either the @S or the partition table is likely to be corrupt!\n"),
9797 /* Fragments not supported */
9798 { PR_0_NO_FRAGMENTS,
9799 N_("@S @b_size = %b, fragsize = %c.\n"
9800 "This version of e2fsck does not support fragment sizes different\n"
9801 "from the @b size.\n"),
9802 PROMPT_NONE, PR_FATAL },
9804 /* Bad blocks_per_group */
9805 { PR_0_BLOCKS_PER_GROUP,
9806 N_("@S @bs_per_group = %b, should have been %c\n"),
9807 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9809 /* Bad first_data_block */
9810 { PR_0_FIRST_DATA_BLOCK,
9811 N_("@S first_data_@b = %b, should have been %c\n"),
9812 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9814 /* Adding UUID to filesystem */
9816 N_("@f did not have a UUID; generating one.\n\n"),
9820 { PR_0_RELOCATE_HINT,
9821 N_("Note: if several inode or block bitmap blocks or part\n"
9822 "of the inode table require relocation, you may wish to try\n"
9823 "running e2fsck with the '-b %S' option first. The problem\n"
9824 "may lie only with the primary block group descriptors, and\n"
9825 "the backup block group descriptors may be OK.\n\n"),
9826 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
9828 /* Miscellaneous superblock corruption */
9829 { PR_0_MISC_CORRUPT_SUPER,
9830 N_("Corruption found in @S. (%s = %N).\n"),
9831 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
9833 /* Error determing physical device size of filesystem */
9834 { PR_0_GETSIZE_ERROR,
9835 N_("Error determining size of the physical @v: %m\n"),
9836 PROMPT_NONE, PR_FATAL },
9838 /* Inode count in superblock is incorrect */
9839 { PR_0_INODE_COUNT_WRONG,
9840 N_("@i count in @S is %i, @s %j.\n"),
9843 { PR_0_HURD_CLEAR_FILETYPE,
9844 N_("The Hurd does not support the filetype feature.\n"),
9847 /* Journal inode is invalid */
9848 { PR_0_JOURNAL_BAD_INODE,
9849 N_("@S has an @n ext3 @j (@i %i).\n"),
9850 PROMPT_CLEAR, PR_PREEN_OK },
9852 /* The external journal has (unsupported) multiple filesystems */
9853 { PR_0_JOURNAL_UNSUPP_MULTIFS,
9854 N_("External @j has multiple @f users (unsupported).\n"),
9855 PROMPT_NONE, PR_FATAL },
9857 /* Can't find external journal */
9858 { PR_0_CANT_FIND_JOURNAL,
9859 N_("Can't find external @j\n"),
9860 PROMPT_NONE, PR_FATAL },
9862 /* External journal has bad superblock */
9863 { PR_0_EXT_JOURNAL_BAD_SUPER,
9864 N_("External @j has bad @S\n"),
9865 PROMPT_NONE, PR_FATAL },
9867 /* Superblock has a bad journal UUID */
9868 { PR_0_JOURNAL_BAD_UUID,
9869 N_("External @j does not support this @f\n"),
9870 PROMPT_NONE, PR_FATAL },
9872 /* Journal has an unknown superblock type */
9873 { PR_0_JOURNAL_UNSUPP_SUPER,
9874 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
9875 "It is likely that your copy of e2fsck is old and/or doesn't "
9876 "support this @j format.\n"
9877 "It is also possible the @j @S is corrupt.\n"),
9878 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
9880 /* Journal superblock is corrupt */
9881 { PR_0_JOURNAL_BAD_SUPER,
9882 N_("Ext3 @j @S is corrupt.\n"),
9883 PROMPT_FIX, PR_PREEN_OK },
9885 /* Superblock flag should be cleared */
9886 { PR_0_JOURNAL_HAS_JOURNAL,
9887 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
9888 PROMPT_CLEAR, PR_PREEN_OK },
9890 /* Superblock flag is incorrect */
9891 { PR_0_JOURNAL_RECOVER_SET,
9892 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
9893 PROMPT_CLEAR, PR_PREEN_OK },
9895 /* Journal has data, but recovery flag is clear */
9896 { PR_0_JOURNAL_RECOVERY_CLEAR,
9897 N_("ext3 recovery flag is clear, but @j has data.\n"),
9900 /* Ask if we should clear the journal */
9901 { PR_0_JOURNAL_RESET_JOURNAL,
9903 PROMPT_NULL, PR_PREEN_NOMSG },
9905 /* Ask if we should run the journal anyway */
9907 N_("Run @j anyway"),
9910 /* Run the journal by default */
9911 { PR_0_JOURNAL_RUN_DEFAULT,
9912 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
9915 /* Clearing orphan inode */
9916 { PR_0_ORPHAN_CLEAR_INODE,
9917 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
9920 /* Illegal block found in orphaned inode */
9921 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
9922 N_("@I @b #%B (%b) found in @o @i %i.\n"),
9925 /* Already cleared block found in orphaned inode */
9926 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
9927 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
9930 /* Illegal orphan inode in superblock */
9931 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
9932 N_("@I @o @i %i in @S.\n"),
9935 /* Illegal inode in orphaned inode list */
9936 { PR_0_ORPHAN_ILLEGAL_INODE,
9937 N_("@I @i %i in @o @i list.\n"),
9940 /* Filesystem revision is 0, but feature flags are set */
9941 { PR_0_FS_REV_LEVEL,
9942 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
9943 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9945 /* Journal superblock has an unknown read-only feature flag set */
9946 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
9947 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
9950 /* Journal superblock has an unknown incompatible feature flag set */
9951 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
9952 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
9955 /* Journal has unsupported version number */
9956 { PR_0_JOURNAL_UNSUPP_VERSION,
9957 N_("@j version not supported by this e2fsck.\n"),
9960 /* Moving journal to hidden file */
9961 { PR_0_MOVE_JOURNAL,
9962 N_("Moving @j from /%s to hidden @i.\n\n"),
9965 /* Error moving journal to hidden file */
9966 { PR_0_ERR_MOVE_JOURNAL,
9967 N_("Error moving @j: %m\n\n"),
9970 /* Clearing V2 journal superblock */
9971 { PR_0_CLEAR_V2_JOURNAL,
9972 N_("Found @n V2 @j @S fields (from V1 @j).\n"
9973 "Clearing fields beyond the V1 @j @S...\n\n"),
9976 /* Backup journal inode blocks */
9978 N_("Backing up @j @i @b information.\n\n"),
9981 /* Reserved blocks w/o resize_inode */
9982 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
9983 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
9984 "is %N; @s zero. "),
9987 /* Resize_inode not enabled, but resize inode is non-zero */
9988 { PR_0_CLEAR_RESIZE_INODE,
9989 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
9992 /* Resize inode invalid */
9993 { PR_0_RESIZE_INODE_INVALID,
9994 N_("Resize @i not valid. "),
9995 PROMPT_RECREATE, 0 },
9999 /* Pass 1: Checking inodes, blocks, and sizes */
10000 { PR_1_PASS_HEADER,
10001 N_("Pass 1: Checking @is, @bs, and sizes\n"),
10004 /* Root directory is not an inode */
10005 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
10008 /* Root directory has dtime set */
10010 N_("@r has dtime set (probably due to old mke2fs). "),
10011 PROMPT_FIX, PR_PREEN_OK },
10013 /* Reserved inode has bad mode */
10014 { PR_1_RESERVED_BAD_MODE,
10015 N_("Reserved @i %i (%Q) has @n mode. "),
10016 PROMPT_CLEAR, PR_PREEN_OK },
10018 /* Deleted inode has zero dtime */
10020 N_("@D @i %i has zero dtime. "),
10021 PROMPT_FIX, PR_PREEN_OK },
10023 /* Inode in use, but dtime set */
10025 N_("@i %i is in use, but has dtime set. "),
10026 PROMPT_FIX, PR_PREEN_OK },
10028 /* Zero-length directory */
10029 { PR_1_ZERO_LENGTH_DIR,
10030 N_("@i %i is a @z @d. "),
10031 PROMPT_CLEAR, PR_PREEN_OK },
10033 /* Block bitmap conflicts with some other fs block */
10034 { PR_1_BB_CONFLICT,
10035 N_("@g %g's @b @B at %b @C.\n"),
10036 PROMPT_RELOCATE, 0 },
10038 /* Inode bitmap conflicts with some other fs block */
10039 { PR_1_IB_CONFLICT,
10040 N_("@g %g's @i @B at %b @C.\n"),
10041 PROMPT_RELOCATE, 0 },
10043 /* Inode table conflicts with some other fs block */
10044 { PR_1_ITABLE_CONFLICT,
10045 N_("@g %g's @i table at %b @C.\n"),
10046 PROMPT_RELOCATE, 0 },
10048 /* Block bitmap is on a bad block */
10049 { PR_1_BB_BAD_BLOCK,
10050 N_("@g %g's @b @B (%b) is bad. "),
10051 PROMPT_RELOCATE, 0 },
10053 /* Inode bitmap is on a bad block */
10054 { PR_1_IB_BAD_BLOCK,
10055 N_("@g %g's @i @B (%b) is bad. "),
10056 PROMPT_RELOCATE, 0 },
10058 /* Inode has incorrect i_size */
10060 N_("@i %i, i_size is %Is, @s %N. "),
10061 PROMPT_FIX, PR_PREEN_OK },
10063 /* Inode has incorrect i_blocks */
10064 { PR_1_BAD_I_BLOCKS,
10065 N_("@i %i, i_@bs is %Ib, @s %N. "),
10066 PROMPT_FIX, PR_PREEN_OK },
10068 /* Illegal blocknumber in inode */
10069 { PR_1_ILLEGAL_BLOCK_NUM,
10070 N_("@I @b #%B (%b) in @i %i. "),
10071 PROMPT_CLEAR, PR_LATCH_BLOCK },
10073 /* Block number overlaps fs metadata */
10074 { PR_1_BLOCK_OVERLAPS_METADATA,
10075 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
10076 PROMPT_CLEAR, PR_LATCH_BLOCK },
10078 /* Inode has illegal blocks (latch question) */
10079 { PR_1_INODE_BLOCK_LATCH,
10080 N_("@i %i has illegal @b(s). "),
10083 /* Too many bad blocks in inode */
10084 { PR_1_TOO_MANY_BAD_BLOCKS,
10085 N_("Too many illegal @bs in @i %i.\n"),
10086 PROMPT_CLEAR_INODE, PR_NO_OK },
10088 /* Illegal block number in bad block inode */
10089 { PR_1_BB_ILLEGAL_BLOCK_NUM,
10090 N_("@I @b #%B (%b) in bad @b @i. "),
10091 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10093 /* Bad block inode has illegal blocks (latch question) */
10094 { PR_1_INODE_BBLOCK_LATCH,
10095 N_("Bad @b @i has illegal @b(s). "),
10098 /* Duplicate or bad blocks in use! */
10099 { PR_1_DUP_BLOCKS_PREENSTOP,
10100 N_("Duplicate or bad @b in use!\n"),
10103 /* Bad block used as bad block indirect block */
10104 { PR_1_BBINODE_BAD_METABLOCK,
10105 N_("Bad @b %b used as bad @b @i indirect @b. "),
10106 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10108 /* Inconsistency can't be fixed prompt */
10109 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
10110 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
10111 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
10113 PROMPT_CONTINUE, PR_PREEN_NOMSG },
10115 /* Bad primary block */
10116 { PR_1_BAD_PRIMARY_BLOCK,
10117 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
10118 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
10120 /* Bad primary block prompt */
10121 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
10122 N_("You can remove this @b from the bad @b list and hope\n"
10123 "that the @b is really OK. But there are no guarantees.\n\n"),
10124 PROMPT_CLEAR, PR_PREEN_NOMSG },
10126 /* Bad primary superblock */
10127 { PR_1_BAD_PRIMARY_SUPERBLOCK,
10128 N_("The primary @S (%b) is on the bad @b list.\n"),
10129 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10131 /* Bad primary block group descriptors */
10132 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
10133 N_("Block %b in the primary @g descriptors "
10134 "is on the bad @b list\n"),
10135 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10137 /* Bad superblock in group */
10138 { PR_1_BAD_SUPERBLOCK,
10139 N_("Warning: Group %g's @S (%b) is bad.\n"),
10140 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10142 /* Bad block group descriptors in group */
10143 { PR_1_BAD_GROUP_DESCRIPTORS,
10144 N_("Warning: Group %g's copy of the @g descriptors has a bad "
10146 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10148 /* Block claimed for no reason */
10149 { PR_1_PROGERR_CLAIMED_BLOCK,
10150 N_("Programming error? @b #%b claimed for no reason in "
10151 "process_bad_@b.\n"),
10152 PROMPT_NONE, PR_PREEN_OK },
10154 /* Error allocating blocks for relocating metadata */
10155 { PR_1_RELOC_BLOCK_ALLOCATE,
10156 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
10157 PROMPT_NONE, PR_PREEN_OK },
10159 /* Error allocating block buffer during relocation process */
10160 { PR_1_RELOC_MEMORY_ALLOCATE,
10161 N_("@A @b buffer for relocating %s\n"),
10162 PROMPT_NONE, PR_PREEN_OK },
10164 /* Relocating metadata group information from X to Y */
10165 { PR_1_RELOC_FROM_TO,
10166 N_("Relocating @g %g's %s from %b to %c...\n"),
10167 PROMPT_NONE, PR_PREEN_OK },
10169 /* Relocating metatdata group information to X */
10171 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
10172 PROMPT_NONE, PR_PREEN_OK },
10174 /* Block read error during relocation process */
10175 { PR_1_RELOC_READ_ERR,
10176 N_("Warning: could not read @b %b of %s: %m\n"),
10177 PROMPT_NONE, PR_PREEN_OK },
10179 /* Block write error during relocation process */
10180 { PR_1_RELOC_WRITE_ERR,
10181 N_("Warning: could not write @b %b for %s: %m\n"),
10182 PROMPT_NONE, PR_PREEN_OK },
10184 /* Error allocating inode bitmap */
10185 { PR_1_ALLOCATE_IBITMAP_ERROR,
10186 N_("@A @i @B (%N): %m\n"),
10187 PROMPT_NONE, PR_FATAL },
10189 /* Error allocating block bitmap */
10190 { PR_1_ALLOCATE_BBITMAP_ERROR,
10191 N_("@A @b @B (%N): %m\n"),
10192 PROMPT_NONE, PR_FATAL },
10194 /* Error allocating icount structure */
10195 { PR_1_ALLOCATE_ICOUNT,
10196 N_("@A icount link information: %m\n"),
10197 PROMPT_NONE, PR_FATAL },
10199 /* Error allocating dbcount */
10200 { PR_1_ALLOCATE_DBCOUNT,
10201 N_("@A @d @b array: %m\n"),
10202 PROMPT_NONE, PR_FATAL },
10204 /* Error while scanning inodes */
10205 { PR_1_ISCAN_ERROR,
10206 N_("Error while scanning @is (%i): %m\n"),
10207 PROMPT_NONE, PR_FATAL },
10209 /* Error while iterating over blocks */
10210 { PR_1_BLOCK_ITERATE,
10211 N_("Error while iterating over @bs in @i %i: %m\n"),
10212 PROMPT_NONE, PR_FATAL },
10214 /* Error while storing inode count information */
10215 { PR_1_ICOUNT_STORE,
10216 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
10217 PROMPT_NONE, PR_FATAL },
10219 /* Error while storing directory block information */
10221 N_("Error storing @d @b information "
10222 "(@i=%i, @b=%b, num=%N): %m\n"),
10223 PROMPT_NONE, PR_FATAL },
10225 /* Error while reading inode (for clearing) */
10227 N_("Error reading @i %i: %m\n"),
10228 PROMPT_NONE, PR_FATAL },
10230 /* Suppress messages prompt */
10231 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
10233 /* Imagic flag set on an inode when filesystem doesn't support it */
10235 N_("@i %i has imagic flag set. "),
10238 /* Immutable flag set on a device or socket inode */
10239 { PR_1_SET_IMMUTABLE,
10240 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
10241 "or append-only flag set. "),
10242 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
10244 /* Compression flag set on an inode when filesystem doesn't support it */
10246 N_("@i %i has @cion flag set on @f without @cion support. "),
10249 /* Non-zero size for device, fifo or socket inode */
10250 { PR_1_SET_NONZSIZE,
10251 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
10252 PROMPT_FIX, PR_PREEN_OK },
10254 /* Filesystem revision is 0, but feature flags are set */
10255 { PR_1_FS_REV_LEVEL,
10256 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
10257 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10259 /* Journal inode is not in use, but contains data */
10260 { PR_1_JOURNAL_INODE_NOT_CLEAR,
10261 N_("@j @i is not in use, but contains data. "),
10262 PROMPT_CLEAR, PR_PREEN_OK },
10264 /* Journal has bad mode */
10265 { PR_1_JOURNAL_BAD_MODE,
10266 N_("@j is not regular file. "),
10267 PROMPT_FIX, PR_PREEN_OK },
10269 /* Deal with inodes that were part of orphan linked list */
10271 N_("@i %i was part of the @o @i list. "),
10272 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
10274 /* Deal with inodes that were part of corrupted orphan linked
10275 list (latch question) */
10276 { PR_1_ORPHAN_LIST_REFUGEES,
10277 N_("@is that were part of a corrupted orphan linked list found. "),
10280 /* Error allocating refcount structure */
10281 { PR_1_ALLOCATE_REFCOUNT,
10282 N_("@A refcount structure (%N): %m\n"),
10283 PROMPT_NONE, PR_FATAL },
10285 /* Error reading extended attribute block */
10286 { PR_1_READ_EA_BLOCK,
10287 N_("Error reading @a @b %b for @i %i. "),
10290 /* Invalid extended attribute block */
10291 { PR_1_BAD_EA_BLOCK,
10292 N_("@i %i has a bad @a @b %b. "),
10295 /* Error reading Extended Attribute block while fixing refcount */
10296 { PR_1_EXTATTR_READ_ABORT,
10297 N_("Error reading @a @b %b (%m). "),
10300 /* Extended attribute reference count incorrect */
10301 { PR_1_EXTATTR_REFCOUNT,
10302 N_("@a @b %b has reference count %B, @s %N. "),
10305 /* Error writing Extended Attribute block while fixing refcount */
10306 { PR_1_EXTATTR_WRITE,
10307 N_("Error writing @a @b %b (%m). "),
10310 /* Multiple EA blocks not supported */
10311 { PR_1_EA_MULTI_BLOCK,
10312 N_("@a @b %b has h_@bs > 1. "),
10315 /* Error allocating EA region allocation structure */
10316 { PR_1_EA_ALLOC_REGION,
10317 N_("@A @a @b %b. "),
10320 /* Error EA allocation collision */
10321 { PR_1_EA_ALLOC_COLLISION,
10322 N_("@a @b %b is corrupt (allocation collision). "),
10325 /* Bad extended attribute name */
10326 { PR_1_EA_BAD_NAME,
10327 N_("@a @b %b is corrupt (@n name). "),
10330 /* Bad extended attribute value */
10331 { PR_1_EA_BAD_VALUE,
10332 N_("@a @b %b is corrupt (@n value). "),
10335 /* Inode too big (latch question) */
10336 { PR_1_INODE_TOOBIG,
10337 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
10339 /* Directory too big */
10341 N_("@b #%B (%b) causes @d to be too big. "),
10342 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10344 /* Regular file too big */
10346 N_("@b #%B (%b) causes file to be too big. "),
10347 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10349 /* Symlink too big */
10350 { PR_1_TOOBIG_SYMLINK,
10351 N_("@b #%B (%b) causes symlink to be too big. "),
10352 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10354 /* INDEX_FL flag set on a non-HTREE filesystem */
10356 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
10357 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10359 /* INDEX_FL flag set on a non-directory */
10360 { PR_1_HTREE_NODIR,
10361 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
10362 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10364 /* Invalid root node in HTREE directory */
10365 { PR_1_HTREE_BADROOT,
10366 N_("@h %i has an @n root node.\n"),
10367 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10369 /* Unsupported hash version in HTREE directory */
10370 { PR_1_HTREE_HASHV,
10371 N_("@h %i has an unsupported hash version (%N)\n"),
10372 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10374 /* Incompatible flag in HTREE root node */
10375 { PR_1_HTREE_INCOMPAT,
10376 N_("@h %i uses an incompatible htree root node flag.\n"),
10377 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10379 /* HTREE too deep */
10380 { PR_1_HTREE_DEPTH,
10381 N_("@h %i has a tree depth (%N) which is too big\n"),
10382 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10384 /* Bad block has indirect block that conflicts with filesystem block */
10385 { PR_1_BB_FS_BLOCK,
10386 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
10388 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10390 /* Resize inode failed */
10391 { PR_1_RESIZE_INODE_CREATE,
10392 N_("Resize @i (re)creation failed: %m."),
10395 /* invalid inode->i_extra_isize */
10396 { PR_1_EXTRA_ISIZE,
10397 N_("@i %i has a extra size (%IS) which is @n\n"),
10398 PROMPT_FIX, PR_PREEN_OK },
10400 /* invalid ea entry->e_name_len */
10401 { PR_1_ATTR_NAME_LEN,
10402 N_("@a in @i %i has a namelen (%N) which is @n\n"),
10403 PROMPT_CLEAR, PR_PREEN_OK },
10405 /* invalid ea entry->e_value_size */
10406 { PR_1_ATTR_VALUE_SIZE,
10407 N_("@a in @i %i has a value size (%N) which is @n\n"),
10408 PROMPT_CLEAR, PR_PREEN_OK },
10410 /* invalid ea entry->e_value_offs */
10411 { PR_1_ATTR_VALUE_OFFSET,
10412 N_("@a in @i %i has a value offset (%N) which is @n\n"),
10413 PROMPT_CLEAR, PR_PREEN_OK },
10415 /* invalid ea entry->e_value_block */
10416 { PR_1_ATTR_VALUE_BLOCK,
10417 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
10418 PROMPT_CLEAR, PR_PREEN_OK },
10420 /* invalid ea entry->e_hash */
10422 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
10423 PROMPT_CLEAR, PR_PREEN_OK },
10425 /* Pass 1b errors */
10427 /* Pass 1B: Rescan for duplicate/bad blocks */
10428 { PR_1B_PASS_HEADER,
10429 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
10430 "Pass 1B: Rescanning for @m @bs\n"),
10433 /* Duplicate/bad block(s) header */
10434 { PR_1B_DUP_BLOCK_HEADER,
10435 N_("@m @b(s) in @i %i:"),
10438 /* Duplicate/bad block(s) in inode */
10441 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
10443 /* Duplicate/bad block(s) end */
10444 { PR_1B_DUP_BLOCK_END,
10446 PROMPT_NONE, PR_PREEN_NOHDR },
10448 /* Error while scanning inodes */
10449 { PR_1B_ISCAN_ERROR,
10450 N_("Error while scanning inodes (%i): %m\n"),
10451 PROMPT_NONE, PR_FATAL },
10453 /* Error allocating inode bitmap */
10454 { PR_1B_ALLOCATE_IBITMAP_ERROR,
10455 N_("@A @i @B (@i_dup_map): %m\n"),
10456 PROMPT_NONE, PR_FATAL },
10458 /* Error while iterating over blocks */
10459 { PR_1B_BLOCK_ITERATE,
10460 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
10463 /* Error adjusting EA refcount */
10464 { PR_1B_ADJ_EA_REFCOUNT,
10465 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
10469 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
10470 { PR_1C_PASS_HEADER,
10471 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
10475 /* Pass 1D: Reconciling multiply-claimed blocks */
10476 { PR_1D_PASS_HEADER,
10477 N_("Pass 1D: Reconciling @m @bs\n"),
10480 /* File has duplicate blocks */
10482 N_("File %Q (@i #%i, mod time %IM) \n"
10483 " has %B @m @b(s), shared with %N file(s):\n"),
10486 /* List of files sharing duplicate blocks */
10487 { PR_1D_DUP_FILE_LIST,
10488 N_("\t%Q (@i #%i, mod time %IM)\n"),
10491 /* File sharing blocks with filesystem metadata */
10492 { PR_1D_SHARE_METADATA,
10493 N_("\t<@f metadata>\n"),
10496 /* Report of how many duplicate/bad inodes */
10497 { PR_1D_NUM_DUP_INODES,
10498 N_("(There are %N @is containing @m @bs.)\n\n"),
10501 /* Duplicated blocks already reassigned or cloned. */
10502 { PR_1D_DUP_BLOCKS_DEALT,
10503 N_("@m @bs already reassigned or cloned.\n\n"),
10506 /* Clone duplicate/bad blocks? */
10507 { PR_1D_CLONE_QUESTION,
10508 "", PROMPT_CLONE, PR_NO_OK },
10511 { PR_1D_DELETE_QUESTION,
10512 "", PROMPT_DELETE, 0 },
10514 /* Couldn't clone file (error) */
10515 { PR_1D_CLONE_ERROR,
10516 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
10518 /* Pass 2 errors */
10520 /* Pass 2: Checking directory structure */
10521 { PR_2_PASS_HEADER,
10522 N_("Pass 2: Checking @d structure\n"),
10525 /* Bad inode number for '.' */
10526 { PR_2_BAD_INODE_DOT,
10527 N_("@n @i number for '.' in @d @i %i.\n"),
10530 /* Directory entry has bad inode number */
10532 N_("@E has @n @i #: %Di.\n"),
10535 /* Directory entry has deleted or unused inode */
10536 { PR_2_UNUSED_INODE,
10537 N_("@E has @D/unused @i %Di. "),
10538 PROMPT_CLEAR, PR_PREEN_OK },
10540 /* Directry entry is link to '.' */
10542 N_("@E @L to '.' "),
10545 /* Directory entry points to inode now located in a bad block */
10547 N_("@E points to @i (%Di) located in a bad @b.\n"),
10550 /* Directory entry contains a link to a directory */
10552 N_("@E @L to @d %P (%Di).\n"),
10555 /* Directory entry contains a link to the root directry */
10557 N_("@E @L to the @r.\n"),
10560 /* Directory entry has illegal characters in its name */
10562 N_("@E has illegal characters in its name.\n"),
10565 /* Missing '.' in directory inode */
10566 { PR_2_MISSING_DOT,
10567 N_("Missing '.' in @d @i %i.\n"),
10570 /* Missing '..' in directory inode */
10571 { PR_2_MISSING_DOT_DOT,
10572 N_("Missing '..' in @d @i %i.\n"),
10575 /* First entry in directory inode doesn't contain '.' */
10576 { PR_2_1ST_NOT_DOT,
10577 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
10580 /* Second entry in directory inode doesn't contain '..' */
10581 { PR_2_2ND_NOT_DOT_DOT,
10582 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
10585 /* i_faddr should be zero */
10587 N_("i_faddr @F %IF, @s zero.\n"),
10590 /* i_file_acl should be zero */
10591 { PR_2_FILE_ACL_ZERO,
10592 N_("i_file_acl @F %If, @s zero.\n"),
10595 /* i_dir_acl should be zero */
10596 { PR_2_DIR_ACL_ZERO,
10597 N_("i_dir_acl @F %Id, @s zero.\n"),
10600 /* i_frag should be zero */
10602 N_("i_frag @F %N, @s zero.\n"),
10605 /* i_fsize should be zero */
10607 N_("i_fsize @F %N, @s zero.\n"),
10610 /* inode has bad mode */
10612 N_("@i %i (%Q) has @n mode (%Im).\n"),
10615 /* directory corrupted */
10616 { PR_2_DIR_CORRUPTED,
10617 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
10618 PROMPT_SALVAGE, 0 },
10620 /* filename too long */
10621 { PR_2_FILENAME_LONG,
10622 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
10623 PROMPT_TRUNCATE, 0 },
10625 /* Directory inode has a missing block (hole) */
10626 { PR_2_DIRECTORY_HOLE,
10627 N_("@d @i %i has an unallocated @b #%B. "),
10628 PROMPT_ALLOCATE, 0 },
10630 /* '.' is not NULL terminated */
10631 { PR_2_DOT_NULL_TERM,
10632 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
10635 /* '..' is not NULL terminated */
10636 { PR_2_DOT_DOT_NULL_TERM,
10637 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
10640 /* Illegal character device inode */
10641 { PR_2_BAD_CHAR_DEV,
10642 N_("@i %i (%Q) is an @I character @v.\n"),
10645 /* Illegal block device inode */
10646 { PR_2_BAD_BLOCK_DEV,
10647 N_("@i %i (%Q) is an @I @b @v.\n"),
10650 /* Duplicate '.' entry */
10652 N_("@E is duplicate '.' @e.\n"),
10655 /* Duplicate '..' entry */
10656 { PR_2_DUP_DOT_DOT,
10657 N_("@E is duplicate '..' @e.\n"),
10660 /* Internal error: couldn't find dir_info */
10662 N_("Internal error: couldn't find dir_info for %i.\n"),
10663 PROMPT_NONE, PR_FATAL },
10665 /* Final rec_len is wrong */
10666 { PR_2_FINAL_RECLEN,
10667 N_("@E has rec_len of %Dr, @s %N.\n"),
10670 /* Error allocating icount structure */
10671 { PR_2_ALLOCATE_ICOUNT,
10672 N_("@A icount structure: %m\n"),
10673 PROMPT_NONE, PR_FATAL },
10675 /* Error iterating over directory blocks */
10676 { PR_2_DBLIST_ITERATE,
10677 N_("Error iterating over @d @bs: %m\n"),
10678 PROMPT_NONE, PR_FATAL },
10680 /* Error reading directory block */
10681 { PR_2_READ_DIRBLOCK,
10682 N_("Error reading @d @b %b (@i %i): %m\n"),
10683 PROMPT_CONTINUE, 0 },
10685 /* Error writing directory block */
10686 { PR_2_WRITE_DIRBLOCK,
10687 N_("Error writing @d @b %b (@i %i): %m\n"),
10688 PROMPT_CONTINUE, 0 },
10690 /* Error allocating new directory block */
10691 { PR_2_ALLOC_DIRBOCK,
10692 N_("@A new @d @b for @i %i (%s): %m\n"),
10695 /* Error deallocating inode */
10696 { PR_2_DEALLOC_INODE,
10697 N_("Error deallocating @i %i: %m\n"),
10698 PROMPT_NONE, PR_FATAL },
10700 /* Directory entry for '.' is big. Split? */
10702 N_("@d @e for '.' is big. "),
10703 PROMPT_SPLIT, PR_NO_OK },
10705 /* Illegal FIFO inode */
10707 N_("@i %i (%Q) is an @I FIFO.\n"),
10710 /* Illegal socket inode */
10712 N_("@i %i (%Q) is an @I socket.\n"),
10715 /* Directory filetype not set */
10716 { PR_2_SET_FILETYPE,
10717 N_("Setting filetype for @E to %N.\n"),
10718 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
10720 /* Directory filetype incorrect */
10721 { PR_2_BAD_FILETYPE,
10722 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
10725 /* Directory filetype set on filesystem */
10726 { PR_2_CLEAR_FILETYPE,
10727 N_("@E has filetype set.\n"),
10728 PROMPT_CLEAR, PR_PREEN_OK },
10730 /* Directory filename is null */
10732 N_("@E has a @z name.\n"),
10735 /* Invalid symlink */
10736 { PR_2_INVALID_SYMLINK,
10737 N_("Symlink %Q (@i #%i) is @n.\n"),
10740 /* i_file_acl (extended attribute block) is bad */
10741 { PR_2_FILE_ACL_BAD,
10742 N_("@a @b @F @n (%If).\n"),
10745 /* Filesystem contains large files, but has no such flag in sb */
10746 { PR_2_FEATURE_LARGE_FILES,
10747 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
10750 /* Node in HTREE directory not referenced */
10751 { PR_2_HTREE_NOTREF,
10752 N_("@p @h %d: node (%B) not referenced\n"),
10755 /* Node in HTREE directory referenced twice */
10756 { PR_2_HTREE_DUPREF,
10757 N_("@p @h %d: node (%B) referenced twice\n"),
10760 /* Node in HTREE directory has bad min hash */
10761 { PR_2_HTREE_MIN_HASH,
10762 N_("@p @h %d: node (%B) has bad min hash\n"),
10765 /* Node in HTREE directory has bad max hash */
10766 { PR_2_HTREE_MAX_HASH,
10767 N_("@p @h %d: node (%B) has bad max hash\n"),
10770 /* Clear invalid HTREE directory */
10771 { PR_2_HTREE_CLEAR,
10772 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
10774 /* Bad block in htree interior node */
10775 { PR_2_HTREE_BADBLK,
10776 N_("@p @h %d (%q): bad @b number %b.\n"),
10777 PROMPT_CLEAR_HTREE, 0 },
10779 /* Error adjusting EA refcount */
10780 { PR_2_ADJ_EA_REFCOUNT,
10781 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
10782 PROMPT_NONE, PR_FATAL },
10784 /* Invalid HTREE root node */
10785 { PR_2_HTREE_BAD_ROOT,
10786 N_("@p @h %d: root node is @n\n"),
10787 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10789 /* Invalid HTREE limit */
10790 { PR_2_HTREE_BAD_LIMIT,
10791 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
10792 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10794 /* Invalid HTREE count */
10795 { PR_2_HTREE_BAD_COUNT,
10796 N_("@p @h %d: node (%B) has @n count (%N)\n"),
10797 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10799 /* HTREE interior node has out-of-order hashes in table */
10800 { PR_2_HTREE_HASH_ORDER,
10801 N_("@p @h %d: node (%B) has an unordered hash table\n"),
10802 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10804 /* Node in HTREE directory has invalid depth */
10805 { PR_2_HTREE_BAD_DEPTH,
10806 N_("@p @h %d: node (%B) has @n depth\n"),
10809 /* Duplicate directory entry found */
10810 { PR_2_DUPLICATE_DIRENT,
10811 N_("Duplicate @E found. "),
10814 /* Non-unique filename found */
10815 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
10816 N_("@E has a non-unique filename.\nRename to %s"),
10819 /* Duplicate directory entry found */
10820 { PR_2_REPORT_DUP_DIRENT,
10821 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
10824 /* Pass 3 errors */
10826 /* Pass 3: Checking directory connectivity */
10827 { PR_3_PASS_HEADER,
10828 N_("Pass 3: Checking @d connectivity\n"),
10831 /* Root inode not allocated */
10832 { PR_3_NO_ROOT_INODE,
10833 N_("@r not allocated. "),
10834 PROMPT_ALLOCATE, 0 },
10836 /* No room in lost+found */
10837 { PR_3_EXPAND_LF_DIR,
10838 N_("No room in @l @d. "),
10839 PROMPT_EXPAND, 0 },
10841 /* Unconnected directory inode */
10842 { PR_3_UNCONNECTED_DIR,
10843 N_("Unconnected @d @i %i (%p)\n"),
10844 PROMPT_CONNECT, 0 },
10846 /* /lost+found not found */
10848 N_("/@l not found. "),
10849 PROMPT_CREATE, PR_PREEN_OK },
10851 /* .. entry is incorrect */
10852 { PR_3_BAD_DOT_DOT,
10853 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
10856 /* Bad or non-existent /lost+found. Cannot reconnect */
10858 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
10861 /* Could not expand /lost+found */
10862 { PR_3_CANT_EXPAND_LPF,
10863 N_("Could not expand /@l: %m\n"),
10866 /* Could not reconnect inode */
10867 { PR_3_CANT_RECONNECT,
10868 N_("Could not reconnect %i: %m\n"),
10871 /* Error while trying to find /lost+found */
10872 { PR_3_ERR_FIND_LPF,
10873 N_("Error while trying to find /@l: %m\n"),
10876 /* Error in ext2fs_new_block while creating /lost+found */
10877 { PR_3_ERR_LPF_NEW_BLOCK,
10878 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
10881 /* Error in ext2fs_new_inode while creating /lost+found */
10882 { PR_3_ERR_LPF_NEW_INODE,
10883 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
10886 /* Error in ext2fs_new_dir_block while creating /lost+found */
10887 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
10888 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
10891 /* Error while writing directory block for /lost+found */
10892 { PR_3_ERR_LPF_WRITE_BLOCK,
10893 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
10896 /* Error while adjusting inode count */
10897 { PR_3_ADJUST_INODE,
10898 N_("Error while adjusting @i count on @i %i\n"),
10901 /* Couldn't fix parent directory -- error */
10902 { PR_3_FIX_PARENT_ERR,
10903 N_("Couldn't fix parent of @i %i: %m\n\n"),
10906 /* Couldn't fix parent directory -- couldn't find it */
10907 { PR_3_FIX_PARENT_NOFIND,
10908 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
10911 /* Error allocating inode bitmap */
10912 { PR_3_ALLOCATE_IBITMAP_ERROR,
10913 N_("@A @i @B (%N): %m\n"),
10914 PROMPT_NONE, PR_FATAL },
10916 /* Error creating root directory */
10917 { PR_3_CREATE_ROOT_ERROR,
10918 N_("Error creating root @d (%s): %m\n"),
10919 PROMPT_NONE, PR_FATAL },
10921 /* Error creating lost and found directory */
10922 { PR_3_CREATE_LPF_ERROR,
10923 N_("Error creating /@l @d (%s): %m\n"),
10924 PROMPT_NONE, PR_FATAL },
10926 /* Root inode is not directory; aborting */
10927 { PR_3_ROOT_NOT_DIR_ABORT,
10928 N_("@r is not a @d; aborting.\n"),
10929 PROMPT_NONE, PR_FATAL },
10931 /* Cannot proceed without a root inode. */
10932 { PR_3_NO_ROOT_INODE_ABORT,
10933 N_("Cannot proceed without a @r.\n"),
10934 PROMPT_NONE, PR_FATAL },
10936 /* Internal error: couldn't find dir_info */
10938 N_("Internal error: couldn't find dir_info for %i.\n"),
10939 PROMPT_NONE, PR_FATAL },
10941 /* Lost+found not a directory */
10943 N_("/@l is not a @d (ino=%i)\n"),
10944 PROMPT_UNLINK, 0 },
10946 /* Pass 3A Directory Optimization */
10948 /* Pass 3A: Optimizing directories */
10949 { PR_3A_PASS_HEADER,
10950 N_("Pass 3A: Optimizing directories\n"),
10951 PROMPT_NONE, PR_PREEN_NOMSG },
10953 /* Error iterating over directories */
10954 { PR_3A_OPTIMIZE_ITER,
10955 N_("Failed to create dirs_to_hash iterator: %m"),
10958 /* Error rehash directory */
10959 { PR_3A_OPTIMIZE_DIR_ERR,
10960 N_("Failed to optimize directory %q (%d): %m"),
10963 /* Rehashing dir header */
10964 { PR_3A_OPTIMIZE_DIR_HEADER,
10965 N_("Optimizing directories: "),
10966 PROMPT_NONE, PR_MSG_ONLY },
10968 /* Rehashing directory %d */
10969 { PR_3A_OPTIMIZE_DIR,
10971 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
10973 /* Rehashing dir end */
10974 { PR_3A_OPTIMIZE_DIR_END,
10976 PROMPT_NONE, PR_PREEN_NOHDR },
10978 /* Pass 4 errors */
10980 /* Pass 4: Checking reference counts */
10981 { PR_4_PASS_HEADER,
10982 N_("Pass 4: Checking reference counts\n"),
10985 /* Unattached zero-length inode */
10986 { PR_4_ZERO_LEN_INODE,
10987 N_("@u @z @i %i. "),
10988 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
10990 /* Unattached inode */
10991 { PR_4_UNATTACHED_INODE,
10993 PROMPT_CONNECT, 0 },
10995 /* Inode ref count wrong */
10996 { PR_4_BAD_REF_COUNT,
10997 N_("@i %i ref count is %Il, @s %N. "),
10998 PROMPT_FIX, PR_PREEN_OK },
11000 { PR_4_INCONSISTENT_COUNT,
11001 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
11002 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
11003 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
11004 "They @s the same!\n"),
11007 /* Pass 5 errors */
11009 /* Pass 5: Checking group summary information */
11010 { PR_5_PASS_HEADER,
11011 N_("Pass 5: Checking @g summary information\n"),
11014 /* Padding at end of inode bitmap is not set. */
11015 { PR_5_INODE_BMAP_PADDING,
11016 N_("Padding at end of @i @B is not set. "),
11017 PROMPT_FIX, PR_PREEN_OK },
11019 /* Padding at end of block bitmap is not set. */
11020 { PR_5_BLOCK_BMAP_PADDING,
11021 N_("Padding at end of @b @B is not set. "),
11022 PROMPT_FIX, PR_PREEN_OK },
11024 /* Block bitmap differences header */
11025 { PR_5_BLOCK_BITMAP_HEADER,
11026 N_("@b @B differences: "),
11027 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
11029 /* Block not used, but marked in bitmap */
11030 { PR_5_BLOCK_UNUSED,
11032 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11034 /* Block used, but not marked used in bitmap */
11037 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11039 /* Block bitmap differences end */
11040 { PR_5_BLOCK_BITMAP_END,
11042 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11044 /* Inode bitmap differences header */
11045 { PR_5_INODE_BITMAP_HEADER,
11046 N_("@i @B differences: "),
11047 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
11049 /* Inode not used, but marked in bitmap */
11050 { PR_5_INODE_UNUSED,
11052 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11054 /* Inode used, but not marked used in bitmap */
11057 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11059 /* Inode bitmap differences end */
11060 { PR_5_INODE_BITMAP_END,
11062 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11064 /* Free inodes count for group wrong */
11065 { PR_5_FREE_INODE_COUNT_GROUP,
11066 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
11067 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11069 /* Directories count for group wrong */
11070 { PR_5_FREE_DIR_COUNT_GROUP,
11071 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
11072 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11074 /* Free inodes count wrong */
11075 { PR_5_FREE_INODE_COUNT,
11076 N_("Free @is count wrong (%i, counted=%j).\n"),
11077 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11079 /* Free blocks count for group wrong */
11080 { PR_5_FREE_BLOCK_COUNT_GROUP,
11081 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
11082 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11084 /* Free blocks count wrong */
11085 { PR_5_FREE_BLOCK_COUNT,
11086 N_("Free @bs count wrong (%b, counted=%c).\n"),
11087 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11089 /* Programming error: bitmap endpoints don't match */
11090 { PR_5_BMAP_ENDPOINTS,
11091 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
11092 "match calculated @B endpoints (%i, %j)\n"),
11093 PROMPT_NONE, PR_FATAL },
11095 /* Internal error: fudging end of bitmap */
11096 { PR_5_FUDGE_BITMAP_ERROR,
11097 N_("Internal error: fudging end of bitmap (%N)\n"),
11098 PROMPT_NONE, PR_FATAL },
11100 /* Error copying in replacement inode bitmap */
11101 { PR_5_COPY_IBITMAP_ERROR,
11102 N_("Error copying in replacement @i @B: %m\n"),
11103 PROMPT_NONE, PR_FATAL },
11105 /* Error copying in replacement block bitmap */
11106 { PR_5_COPY_BBITMAP_ERROR,
11107 N_("Error copying in replacement @b @B: %m\n"),
11108 PROMPT_NONE, PR_FATAL },
11110 /* Block range not used, but marked in bitmap */
11111 { PR_5_BLOCK_RANGE_UNUSED,
11113 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11115 /* Block range used, but not marked used in bitmap */
11116 { PR_5_BLOCK_RANGE_USED,
11118 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11120 /* Inode range not used, but marked in bitmap */
11121 { PR_5_INODE_RANGE_UNUSED,
11123 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11125 /* Inode range used, but not marked used in bitmap */
11126 { PR_5_INODE_RANGE_USED,
11128 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11134 * This is the latch flags register. It allows several problems to be
11135 * "latched" together. This means that the user has to answer but one
11136 * question for the set of problems, and all of the associated
11137 * problems will be either fixed or not fixed.
11139 static struct latch_descr pr_latch_info[] = {
11140 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
11141 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
11142 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
11143 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
11144 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
11145 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
11146 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
11147 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
11148 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
11152 static const struct e2fsck_problem *find_problem(problem_t code)
11156 for (i=0; problem_table[i].e2p_code; i++) {
11157 if (problem_table[i].e2p_code == code)
11158 return &problem_table[i];
11163 static struct latch_descr *find_latch(int code)
11167 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
11168 if (pr_latch_info[i].latch_code == code)
11169 return &pr_latch_info[i];
11174 int end_problem_latch(e2fsck_t ctx, int mask)
11176 struct latch_descr *ldesc;
11177 struct problem_context pctx;
11180 ldesc = find_latch(mask);
11181 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
11182 clear_problem_context(&pctx);
11183 answer = fix_problem(ctx, ldesc->end_message, &pctx);
11185 ldesc->flags &= ~(PRL_VARIABLE);
11189 int set_latch_flags(int mask, int setflags, int clearflags)
11191 struct latch_descr *ldesc;
11193 ldesc = find_latch(mask);
11196 ldesc->flags |= setflags;
11197 ldesc->flags &= ~clearflags;
11201 void clear_problem_context(struct problem_context *ctx)
11203 memset(ctx, 0, sizeof(struct problem_context));
11204 ctx->blkcount = -1;
11208 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
11210 ext2_filsys fs = ctx->fs;
11211 const struct e2fsck_problem *ptr;
11212 struct latch_descr *ldesc = 0;
11213 const char *message;
11214 int def_yn, answer, ans;
11215 int print_answer = 0;
11218 ptr = find_problem(code);
11220 printf(_("Unhandled error code (0x%x)!\n"), code);
11224 if ((ptr->flags & PR_NO_DEFAULT) ||
11225 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
11226 (ctx->options & E2F_OPT_NO))
11230 * Do special latch processing. This is where we ask the
11231 * latch question, if it exists
11233 if (ptr->flags & PR_LATCH_MASK) {
11234 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
11235 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
11236 ans = fix_problem(ctx, ldesc->question, pctx);
11238 ldesc->flags |= PRL_YES;
11240 ldesc->flags |= PRL_NO;
11241 ldesc->flags |= PRL_LATCHED;
11243 if (ldesc->flags & PRL_SUPPRESS)
11246 if ((ptr->flags & PR_PREEN_NOMSG) &&
11247 (ctx->options & E2F_OPT_PREEN))
11249 if ((ptr->flags & PR_NO_NOMSG) &&
11250 (ctx->options & E2F_OPT_NO))
11253 message = ptr->e2p_description;
11254 if ((ctx->options & E2F_OPT_PREEN) &&
11255 !(ptr->flags & PR_PREEN_NOHDR)) {
11256 printf("%s: ", ctx->device_name ?
11257 ctx->device_name : ctx->filesystem_name);
11260 print_e2fsck_message(ctx, _(message), pctx, 1);
11262 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
11265 if (ptr->flags & PR_FATAL)
11266 fatal_error(ctx, 0);
11268 if (ptr->prompt == PROMPT_NONE) {
11269 if (ptr->flags & PR_NOCOLLATE)
11274 if (ctx->options & E2F_OPT_PREEN) {
11276 if (!(ptr->flags & PR_PREEN_NOMSG))
11278 } else if ((ptr->flags & PR_LATCH_MASK) &&
11279 (ldesc->flags & (PRL_YES | PRL_NO))) {
11282 if (ldesc->flags & PRL_YES)
11287 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
11288 if (!answer && !(ptr->flags & PR_NO_OK))
11289 ext2fs_unmark_valid(fs);
11292 printf("%s.\n", answer ?
11293 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
11297 if ((ptr->prompt == PROMPT_ABORT) && answer)
11298 fatal_error(ctx, 0);
11300 if (ptr->flags & PR_AFTER_CODE)
11301 answer = fix_problem(ctx, ptr->second_code, pctx);
11307 * linux/fs/recovery.c
11309 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
11313 * Maintain information about the progress of the recovery job, so that
11314 * the different passes can carry information between them.
11316 struct recovery_info
11318 tid_t start_transaction;
11319 tid_t end_transaction;
11323 int nr_revoke_hits;
11326 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
11327 static int do_one_pass(journal_t *journal,
11328 struct recovery_info *info, enum passtype pass);
11329 static int scan_revoke_records(journal_t *, struct buffer_head *,
11330 tid_t, struct recovery_info *);
11333 * Read a block from the journal
11336 static int jread(struct buffer_head **bhp, journal_t *journal,
11337 unsigned int offset)
11340 unsigned long blocknr;
11341 struct buffer_head *bh;
11345 err = journal_bmap(journal, offset, &blocknr);
11348 printf ("JBD: bad block at offset %u\n", offset);
11352 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
11356 if (!buffer_uptodate(bh)) {
11357 /* If this is a brand new buffer, start readahead.
11358 Otherwise, we assume we are already reading it. */
11359 if (!buffer_req(bh))
11360 do_readahead(journal, offset);
11361 wait_on_buffer(bh);
11364 if (!buffer_uptodate(bh)) {
11365 printf ("JBD: Failed to read block at offset %u\n", offset);
11376 * Count the number of in-use tags in a journal descriptor block.
11379 static int count_tags(struct buffer_head *bh, int size)
11382 journal_block_tag_t * tag;
11385 tagp = &bh->b_data[sizeof(journal_header_t)];
11387 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
11388 tag = (journal_block_tag_t *) tagp;
11391 tagp += sizeof(journal_block_tag_t);
11392 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
11395 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
11403 /* Make sure we wrap around the log correctly! */
11404 #define wrap(journal, var) \
11406 if (var >= (journal)->j_last) \
11407 var -= ((journal)->j_last - (journal)->j_first); \
11411 * int journal_recover(journal_t *journal) - recovers a on-disk journal
11412 * @journal: the journal to recover
11414 * The primary function for recovering the log contents when mounting a
11415 * journaled device.
11417 * Recovery is done in three passes. In the first pass, we look for the
11418 * end of the log. In the second, we assemble the list of revoke
11419 * blocks. In the third and final pass, we replay any un-revoked blocks
11422 int journal_recover(journal_t *journal)
11425 journal_superblock_t * sb;
11427 struct recovery_info info;
11429 memset(&info, 0, sizeof(info));
11430 sb = journal->j_superblock;
11433 * The journal superblock's s_start field (the current log head)
11434 * is always zero if, and only if, the journal was cleanly
11438 if (!sb->s_start) {
11439 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
11443 err = do_one_pass(journal, &info, PASS_SCAN);
11445 err = do_one_pass(journal, &info, PASS_REVOKE);
11447 err = do_one_pass(journal, &info, PASS_REPLAY);
11449 /* Restart the log at the next transaction ID, thus invalidating
11450 * any existing commit records in the log. */
11451 journal->j_transaction_sequence = ++info.end_transaction;
11453 journal_clear_revoke(journal);
11454 sync_blockdev(journal->j_fs_dev);
11458 static int do_one_pass(journal_t *journal,
11459 struct recovery_info *info, enum passtype pass)
11461 unsigned int first_commit_ID, next_commit_ID;
11462 unsigned long next_log_block;
11463 int err, success = 0;
11464 journal_superblock_t * sb;
11465 journal_header_t * tmp;
11466 struct buffer_head * bh;
11467 unsigned int sequence;
11470 /* Precompute the maximum metadata descriptors in a descriptor block */
11471 int MAX_BLOCKS_PER_DESC;
11472 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
11473 / sizeof(journal_block_tag_t));
11476 * First thing is to establish what we expect to find in the log
11477 * (in terms of transaction IDs), and where (in terms of log
11478 * block offsets): query the superblock.
11481 sb = journal->j_superblock;
11482 next_commit_ID = ntohl(sb->s_sequence);
11483 next_log_block = ntohl(sb->s_start);
11485 first_commit_ID = next_commit_ID;
11486 if (pass == PASS_SCAN)
11487 info->start_transaction = first_commit_ID;
11490 * Now we walk through the log, transaction by transaction,
11491 * making sure that each transaction has a commit block in the
11492 * expected place. Each complete transaction gets replayed back
11493 * into the main filesystem.
11499 journal_block_tag_t * tag;
11500 struct buffer_head * obh;
11501 struct buffer_head * nbh;
11503 /* If we already know where to stop the log traversal,
11504 * check right now that we haven't gone past the end of
11507 if (pass != PASS_SCAN)
11508 if (tid_geq(next_commit_ID, info->end_transaction))
11511 /* Skip over each chunk of the transaction looking
11512 * either the next descriptor block or the final commit
11515 err = jread(&bh, journal, next_log_block);
11520 wrap(journal, next_log_block);
11522 /* What kind of buffer is it?
11524 * If it is a descriptor block, check that it has the
11525 * expected sequence number. Otherwise, we're all done
11528 tmp = (journal_header_t *)bh->b_data;
11530 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
11535 blocktype = ntohl(tmp->h_blocktype);
11536 sequence = ntohl(tmp->h_sequence);
11538 if (sequence != next_commit_ID) {
11543 /* OK, we have a valid descriptor block which matches
11544 * all of the sequence number checks. What are we going
11545 * to do with it? That depends on the pass... */
11547 switch(blocktype) {
11548 case JFS_DESCRIPTOR_BLOCK:
11549 /* If it is a valid descriptor block, replay it
11550 * in pass REPLAY; otherwise, just skip over the
11551 * blocks it describes. */
11552 if (pass != PASS_REPLAY) {
11554 count_tags(bh, journal->j_blocksize);
11555 wrap(journal, next_log_block);
11560 /* A descriptor block: we can now write all of
11561 * the data blocks. Yay, useful work is finally
11562 * getting done here! */
11564 tagp = &bh->b_data[sizeof(journal_header_t)];
11565 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
11566 <= journal->j_blocksize) {
11567 unsigned long io_block;
11569 tag = (journal_block_tag_t *) tagp;
11570 flags = ntohl(tag->t_flags);
11572 io_block = next_log_block++;
11573 wrap(journal, next_log_block);
11574 err = jread(&obh, journal, io_block);
11576 /* Recover what we can, but
11577 * report failure at the end. */
11579 printf ("JBD: IO error %d recovering "
11580 "block %ld in log\n",
11583 unsigned long blocknr;
11585 blocknr = ntohl(tag->t_blocknr);
11587 /* If the block has been
11588 * revoked, then we're all done
11590 if (journal_test_revoke
11594 ++info->nr_revoke_hits;
11598 /* Find a buffer for the new
11599 * data being restored */
11600 nbh = getblk(journal->j_fs_dev,
11602 journal->j_blocksize);
11604 printf ("JBD: Out of memory "
11605 "during recovery.\n");
11613 memcpy(nbh->b_data, obh->b_data,
11614 journal->j_blocksize);
11615 if (flags & JFS_FLAG_ESCAPE) {
11616 *((unsigned int *)bh->b_data) =
11617 htonl(JFS_MAGIC_NUMBER);
11620 mark_buffer_uptodate(nbh, 1);
11621 mark_buffer_dirty(nbh);
11622 ++info->nr_replays;
11623 /* ll_rw_block(WRITE, 1, &nbh); */
11624 unlock_buffer(nbh);
11630 tagp += sizeof(journal_block_tag_t);
11631 if (!(flags & JFS_FLAG_SAME_UUID))
11634 if (flags & JFS_FLAG_LAST_TAG)
11641 case JFS_COMMIT_BLOCK:
11642 /* Found an expected commit block: not much to
11643 * do other than move on to the next sequence
11649 case JFS_REVOKE_BLOCK:
11650 /* If we aren't in the REVOKE pass, then we can
11651 * just skip over this block. */
11652 if (pass != PASS_REVOKE) {
11657 err = scan_revoke_records(journal, bh,
11658 next_commit_ID, info);
11671 * We broke out of the log scan loop: either we came to the
11672 * known end of the log or we found an unexpected block in the
11673 * log. If the latter happened, then we know that the "current"
11674 * transaction marks the end of the valid log.
11677 if (pass == PASS_SCAN)
11678 info->end_transaction = next_commit_ID;
11680 /* It's really bad news if different passes end up at
11681 * different places (but possible due to IO errors). */
11682 if (info->end_transaction != next_commit_ID) {
11683 printf ("JBD: recovery pass %d ended at "
11684 "transaction %u, expected %u\n",
11685 pass, next_commit_ID, info->end_transaction);
11698 /* Scan a revoke record, marking all blocks mentioned as revoked. */
11700 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
11701 tid_t sequence, struct recovery_info *info)
11703 journal_revoke_header_t *header;
11706 header = (journal_revoke_header_t *) bh->b_data;
11707 offset = sizeof(journal_revoke_header_t);
11708 max = ntohl(header->r_count);
11710 while (offset < max) {
11711 unsigned long blocknr;
11714 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
11716 err = journal_set_revoke(journal, blocknr, sequence);
11719 ++info->nr_revokes;
11726 * rehash.c --- rebuild hash tree directories
11728 * This algorithm is designed for simplicity of implementation and to
11729 * pack the directory as much as possible. It however requires twice
11730 * as much memory as the size of the directory. The maximum size
11731 * directory supported using a 4k blocksize is roughly a gigabyte, and
11732 * so there may very well be problems with machines that don't have
11733 * virtual memory, and obscenely large directories.
11735 * An alternate algorithm which is much more disk intensive could be
11736 * written, and probably will need to be written in the future. The
11737 * design goals of such an algorithm are: (a) use (roughly) constant
11738 * amounts of memory, no matter how large the directory, (b) the
11739 * directory must be safe at all times, even if e2fsck is interrupted
11740 * in the middle, (c) we must use minimal amounts of extra disk
11741 * blocks. This pretty much requires an incremental approach, where
11742 * we are reading from one part of the directory, and inserting into
11743 * the front half. So the algorithm will have to keep track of a
11744 * moving block boundary between the new tree and the old tree, and
11745 * files will need to be moved from the old directory and inserted
11746 * into the new tree. If the new directory requires space which isn't
11747 * yet available, blocks from the beginning part of the old directory
11748 * may need to be moved to the end of the directory to make room for
11751 * --------------------------------------------------------
11752 * | new tree | | old tree |
11753 * --------------------------------------------------------
11755 * tail new head old
11757 * This is going to be a pain in the tuckus to implement, and will
11758 * require a lot more disk accesses. So I'm going to skip it for now;
11759 * it's only really going to be an issue for really, really big
11760 * filesystems (when we reach the level of tens of millions of files
11761 * in a single directory). It will probably be easier to simply
11762 * require that e2fsck use VM first.
11765 struct fill_dir_struct {
11767 struct ext2_inode *inode;
11770 struct hash_entry *harray;
11771 int max_array, num_array;
11777 struct hash_entry {
11778 ext2_dirhash_t hash;
11779 ext2_dirhash_t minor_hash;
11780 struct ext2_dir_entry *dir;
11787 ext2_dirhash_t *hashes;
11790 static int fill_dir_block(ext2_filsys fs,
11792 e2_blkcnt_t blockcnt,
11793 blk_t ref_block FSCK_ATTR((unused)),
11794 int ref_offset FSCK_ATTR((unused)),
11797 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
11798 struct hash_entry *new_array, *ent;
11799 struct ext2_dir_entry *dirent;
11801 unsigned int offset, dir_offset;
11806 offset = blockcnt * fs->blocksize;
11807 if (offset + fs->blocksize > fd->inode->i_size) {
11808 fd->err = EXT2_ET_DIR_CORRUPTED;
11809 return BLOCK_ABORT;
11811 dir = (fd->buf+offset);
11812 if (HOLE_BLKADDR(*block_nr)) {
11813 memset(dir, 0, fs->blocksize);
11814 dirent = (struct ext2_dir_entry *) dir;
11815 dirent->rec_len = fs->blocksize;
11817 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
11819 return BLOCK_ABORT;
11821 /* While the directory block is "hot", index it. */
11823 while (dir_offset < fs->blocksize) {
11824 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
11825 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
11826 (dirent->rec_len < 8) ||
11827 ((dirent->rec_len % 4) != 0) ||
11828 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
11829 fd->err = EXT2_ET_DIR_CORRUPTED;
11830 return BLOCK_ABORT;
11832 dir_offset += dirent->rec_len;
11833 if (dirent->inode == 0)
11835 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
11836 (dirent->name[0] == '.'))
11838 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
11839 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
11840 fd->parent = dirent->inode;
11843 if (fd->num_array >= fd->max_array) {
11844 new_array = realloc(fd->harray,
11845 sizeof(struct hash_entry) * (fd->max_array+500));
11848 return BLOCK_ABORT;
11850 fd->harray = new_array;
11851 fd->max_array += 500;
11853 ent = fd->harray + fd->num_array++;
11855 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
11857 ent->hash = ent->minor_hash = 0;
11859 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
11861 dirent->name_len & 0xFF,
11862 fs->super->s_hash_seed,
11863 &ent->hash, &ent->minor_hash);
11865 return BLOCK_ABORT;
11872 /* Used for sorting the hash entry */
11873 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
11875 const struct hash_entry *he_a = (const struct hash_entry *) a;
11876 const struct hash_entry *he_b = (const struct hash_entry *) b;
11880 min_len = he_a->dir->name_len;
11881 if (min_len > he_b->dir->name_len)
11882 min_len = he_b->dir->name_len;
11884 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
11886 if (he_a->dir->name_len > he_b->dir->name_len)
11888 else if (he_a->dir->name_len < he_b->dir->name_len)
11891 ret = he_b->dir->inode - he_a->dir->inode;
11896 /* Used for sorting the hash entry */
11897 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
11899 const struct hash_entry *he_a = (const struct hash_entry *) a;
11900 const struct hash_entry *he_b = (const struct hash_entry *) b;
11903 if (he_a->hash > he_b->hash)
11905 else if (he_a->hash < he_b->hash)
11908 if (he_a->minor_hash > he_b->minor_hash)
11910 else if (he_a->minor_hash < he_b->minor_hash)
11913 ret = name_cmp(a, b);
11918 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
11924 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
11927 outdir->buf = new_mem;
11928 new_mem = realloc(outdir->hashes,
11929 blocks * sizeof(ext2_dirhash_t));
11932 outdir->hashes = new_mem;
11934 outdir->buf = malloc(blocks * fs->blocksize);
11935 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
11938 outdir->max = blocks;
11942 static void free_out_dir(struct out_dir *outdir)
11945 free(outdir->hashes);
11950 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
11955 if (outdir->num >= outdir->max) {
11956 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
11960 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
11961 memset(*ret, 0, fs->blocksize);
11966 * This function is used to make a unique filename. We do this by
11967 * appending ~0, and then incrementing the number. However, we cannot
11968 * expand the length of the filename beyond the padding available in
11969 * the directory entry.
11971 static void mutate_name(char *str, __u16 *len)
11974 __u16 l = *len & 0xFF, h = *len & 0xff00;
11977 * First check to see if it looks the name has been mutated
11980 for (i = l-1; i > 0; i--) {
11981 if (!isdigit(str[i]))
11984 if ((i == l-1) || (str[i] != '~')) {
11985 if (((l-1) & 3) < 2)
11994 for (i = l-1; i >= 0; i--) {
11995 if (isdigit(str[i])) {
12007 else if (str[0] == 'Z') {
12012 } else if (i > 0) {
12025 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
12027 struct fill_dir_struct *fd)
12029 struct problem_context pctx;
12030 struct hash_entry *ent, *prev;
12033 char new_name[256];
12036 clear_problem_context(&pctx);
12039 for (i=1; i < fd->num_array; i++) {
12040 ent = fd->harray + i;
12042 if (!ent->dir->inode ||
12043 ((ent->dir->name_len & 0xFF) !=
12044 (prev->dir->name_len & 0xFF)) ||
12045 (strncmp(ent->dir->name, prev->dir->name,
12046 ent->dir->name_len & 0xFF)))
12048 pctx.dirent = ent->dir;
12049 if ((ent->dir->inode == prev->dir->inode) &&
12050 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
12051 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
12052 ent->dir->inode = 0;
12056 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
12057 new_len = ent->dir->name_len;
12058 mutate_name(new_name, &new_len);
12059 for (j=0; j < fd->num_array; j++) {
12061 ((ent->dir->name_len & 0xFF) !=
12062 (fd->harray[j].dir->name_len & 0xFF)) ||
12063 (strncmp(new_name, fd->harray[j].dir->name,
12066 mutate_name(new_name, &new_len);
12070 new_name[new_len & 0xFF] = 0;
12071 pctx.str = new_name;
12072 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
12073 memcpy(ent->dir->name, new_name, new_len & 0xFF);
12074 ent->dir->name_len = new_len;
12075 ext2fs_dirhash(fs->super->s_def_hash_version,
12077 ent->dir->name_len & 0xFF,
12078 fs->super->s_hash_seed,
12079 &ent->hash, &ent->minor_hash);
12087 static errcode_t copy_dir_entries(ext2_filsys fs,
12088 struct fill_dir_struct *fd,
12089 struct out_dir *outdir)
12093 struct hash_entry *ent;
12094 struct ext2_dir_entry *dirent;
12095 int i, rec_len, left;
12096 ext2_dirhash_t prev_hash;
12100 retval = alloc_size_dir(fs, outdir,
12101 (fd->dir_size / fs->blocksize) + 2);
12104 outdir->num = fd->compress ? 0 : 1;
12106 outdir->hashes[0] = 0;
12108 if ((retval = get_next_block(fs, outdir, &block_start)))
12110 dirent = (struct ext2_dir_entry *) block_start;
12111 left = fs->blocksize;
12112 for (i=0; i < fd->num_array; i++) {
12113 ent = fd->harray + i;
12114 if (ent->dir->inode == 0)
12116 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
12117 if (rec_len > left) {
12119 dirent->rec_len += left;
12120 if ((retval = get_next_block(fs, outdir,
12125 left = fs->blocksize - offset;
12126 dirent = (struct ext2_dir_entry *) (block_start + offset);
12128 if (ent->hash == prev_hash)
12129 outdir->hashes[outdir->num-1] = ent->hash | 1;
12131 outdir->hashes[outdir->num-1] = ent->hash;
12133 dirent->inode = ent->dir->inode;
12134 dirent->name_len = ent->dir->name_len;
12135 dirent->rec_len = rec_len;
12136 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
12140 dirent->rec_len += left;
12144 prev_hash = ent->hash;
12147 dirent->rec_len += left;
12153 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
12154 ext2_ino_t ino, ext2_ino_t parent)
12156 struct ext2_dir_entry *dir;
12157 struct ext2_dx_root_info *root;
12158 struct ext2_dx_countlimit *limits;
12161 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
12162 filetype = EXT2_FT_DIR << 8;
12164 memset(buf, 0, fs->blocksize);
12165 dir = (struct ext2_dir_entry *) buf;
12167 dir->name[0] = '.';
12168 dir->name_len = 1 | filetype;
12170 dir = (struct ext2_dir_entry *) (buf + 12);
12171 dir->inode = parent;
12172 dir->name[0] = '.';
12173 dir->name[1] = '.';
12174 dir->name_len = 2 | filetype;
12175 dir->rec_len = fs->blocksize - 12;
12177 root = (struct ext2_dx_root_info *) (buf+24);
12178 root->reserved_zero = 0;
12179 root->hash_version = fs->super->s_def_hash_version;
12180 root->info_length = 8;
12181 root->indirect_levels = 0;
12182 root->unused_flags = 0;
12184 limits = (struct ext2_dx_countlimit *) (buf+32);
12185 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
12192 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
12194 struct ext2_dir_entry *dir;
12195 struct ext2_dx_countlimit *limits;
12197 memset(buf, 0, fs->blocksize);
12198 dir = (struct ext2_dir_entry *) buf;
12200 dir->rec_len = fs->blocksize;
12202 limits = (struct ext2_dx_countlimit *) (buf+8);
12203 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
12206 return (struct ext2_dx_entry *) limits;
12210 * This function takes the leaf nodes which have been written in
12211 * outdir, and populates the root node and any necessary interior nodes.
12213 static errcode_t calculate_tree(ext2_filsys fs,
12214 struct out_dir *outdir,
12218 struct ext2_dx_root_info *root_info;
12219 struct ext2_dx_entry *root, *dx_ent = 0;
12220 struct ext2_dx_countlimit *root_limit, *limit;
12222 char * block_start;
12223 int i, c1, c2, nblks;
12224 int limit_offset, root_offset;
12226 root_info = set_root_node(fs, outdir->buf, ino, parent);
12227 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
12228 root_info->info_length;
12229 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
12230 c1 = root_limit->limit;
12231 nblks = outdir->num;
12233 /* Write out the pointer blocks */
12234 if (nblks-1 <= c1) {
12235 /* Just write out the root block, and we're done */
12236 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
12237 for (i=1; i < nblks; i++) {
12238 root->block = ext2fs_cpu_to_le32(i);
12241 ext2fs_cpu_to_le32(outdir->hashes[i]);
12248 root_info->indirect_levels = 1;
12249 for (i=1; i < nblks; i++) {
12254 limit->limit = limit->count =
12255 ext2fs_cpu_to_le16(limit->limit);
12256 root = (struct ext2_dx_entry *)
12257 (outdir->buf + root_offset);
12258 root->block = ext2fs_cpu_to_le32(outdir->num);
12261 ext2fs_cpu_to_le32(outdir->hashes[i]);
12262 if ((retval = get_next_block(fs, outdir,
12265 dx_ent = set_int_node(fs, block_start);
12266 limit = (struct ext2_dx_countlimit *) dx_ent;
12268 root_offset += sizeof(struct ext2_dx_entry);
12271 dx_ent->block = ext2fs_cpu_to_le32(i);
12272 if (c2 != limit->limit)
12274 ext2fs_cpu_to_le32(outdir->hashes[i]);
12278 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
12279 limit->limit = ext2fs_cpu_to_le16(limit->limit);
12281 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
12282 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
12283 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
12288 struct write_dir_struct {
12289 struct out_dir *outdir;
12296 * Helper function which writes out a directory block.
12298 static int write_dir_block(ext2_filsys fs,
12300 e2_blkcnt_t blockcnt,
12301 blk_t ref_block FSCK_ATTR((unused)),
12302 int ref_offset FSCK_ATTR((unused)),
12305 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
12309 if (*block_nr == 0)
12311 if (blockcnt >= wd->outdir->num) {
12312 e2fsck_read_bitmaps(wd->ctx);
12314 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
12315 ext2fs_block_alloc_stats(fs, blk, -1);
12318 return BLOCK_CHANGED;
12323 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
12324 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
12326 return BLOCK_ABORT;
12330 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
12331 struct out_dir *outdir,
12332 ext2_ino_t ino, int compress)
12334 struct write_dir_struct wd;
12336 struct ext2_inode inode;
12338 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
12342 wd.outdir = outdir;
12347 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12348 write_dir_block, &wd);
12354 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12356 inode.i_flags &= ~EXT2_INDEX_FL;
12358 inode.i_flags |= EXT2_INDEX_FL;
12359 inode.i_size = outdir->num * fs->blocksize;
12360 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
12361 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
12366 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
12368 ext2_filsys fs = ctx->fs;
12370 struct ext2_inode inode;
12372 struct fill_dir_struct fd;
12373 struct out_dir outdir;
12375 outdir.max = outdir.num = 0;
12378 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12382 dir_buf = malloc(inode.i_size);
12386 fd.max_array = inode.i_size / 32;
12388 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
12398 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
12399 (inode.i_size / fs->blocksize) < 2)
12403 /* Read in the entire directory into memory */
12404 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12405 fill_dir_block, &fd);
12412 printf("%d entries (%d bytes) found in inode %d\n",
12413 fd.num_array, fd.dir_size, ino);
12416 /* Sort the list */
12419 qsort(fd.harray+2, fd.num_array-2,
12420 sizeof(struct hash_entry), name_cmp);
12422 qsort(fd.harray, fd.num_array,
12423 sizeof(struct hash_entry), hash_cmp);
12426 * Look for duplicates
12428 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
12431 if (ctx->options & E2F_OPT_NO) {
12437 * Copy the directory entries. In a htree directory these
12438 * will become the leaf nodes.
12440 retval = copy_dir_entries(fs, &fd, &outdir);
12444 free(dir_buf); dir_buf = 0;
12446 if (!fd.compress) {
12447 /* Calculate the interior nodes */
12448 retval = calculate_tree(fs, &outdir, ino, fd.parent);
12453 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
12459 free_out_dir(&outdir);
12463 void e2fsck_rehash_directories(e2fsck_t ctx)
12465 struct problem_context pctx;
12466 #ifdef RESOURCE_TRACK
12467 struct resource_track rtrack;
12469 struct dir_info *dir;
12470 ext2_u32_iterate iter;
12473 int i, cur, max, all_dirs, dir_index, first = 1;
12475 #ifdef RESOURCE_TRACK
12476 init_resource_track(&rtrack);
12479 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
12481 if (!ctx->dirs_to_hash && !all_dirs)
12484 e2fsck_get_lost_and_found(ctx, 0);
12486 clear_problem_context(&pctx);
12488 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
12492 max = e2fsck_get_num_dirinfo(ctx);
12494 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
12497 pctx.errcode = retval;
12498 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
12501 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
12505 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
12509 if (!ext2fs_u32_list_iterate(iter, &ino))
12512 if (ino == ctx->lost_and_found)
12516 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
12520 fix_problem(ctx, PR_3A_OPTIMIZE_DIR, &pctx);
12522 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
12523 if (pctx.errcode) {
12524 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12525 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
12527 if (ctx->progress && !ctx->progress_fd)
12528 e2fsck_simple_progress(ctx, "Rebuilding directory",
12529 100.0 * (float) (++cur) / (float) max, ino);
12531 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12533 ext2fs_u32_list_iterate_end(iter);
12535 ext2fs_u32_list_free(ctx->dirs_to_hash);
12536 ctx->dirs_to_hash = 0;
12538 #ifdef RESOURCE_TRACK
12539 if (ctx->options & E2F_OPT_TIME2) {
12540 e2fsck_clear_progbar(ctx);
12541 print_resource_track("Pass 3A", &rtrack);
12547 * linux/fs/revoke.c
12549 * Journal revoke routines for the generic filesystem journaling code;
12550 * part of the ext2fs journaling system.
12552 * Revoke is the mechanism used to prevent old log records for deleted
12553 * metadata from being replayed on top of newer data using the same
12554 * blocks. The revoke mechanism is used in two separate places:
12556 * + Commit: during commit we write the entire list of the current
12557 * transaction's revoked blocks to the journal
12559 * + Recovery: during recovery we record the transaction ID of all
12560 * revoked blocks. If there are multiple revoke records in the log
12561 * for a single block, only the last one counts, and if there is a log
12562 * entry for a block beyond the last revoke, then that log entry still
12565 * We can get interactions between revokes and new log data within a
12566 * single transaction:
12568 * Block is revoked and then journaled:
12569 * The desired end result is the journaling of the new block, so we
12570 * cancel the revoke before the transaction commits.
12572 * Block is journaled and then revoked:
12573 * The revoke must take precedence over the write of the block, so we
12574 * need either to cancel the journal entry or to write the revoke
12575 * later in the log than the log block. In this case, we choose the
12576 * latter: journaling a block cancels any revoke record for that block
12577 * in the current transaction, so any revoke for that block in the
12578 * transaction must have happened after the block was journaled and so
12579 * the revoke must take precedence.
12581 * Block is revoked and then written as data:
12582 * The data write is allowed to succeed, but the revoke is _not_
12583 * cancelled. We still need to prevent old log records from
12584 * overwriting the new data. We don't even need to clear the revoke
12587 * Revoke information on buffers is a tri-state value:
12589 * RevokeValid clear: no cached revoke status, need to look it up
12590 * RevokeValid set, Revoked clear:
12591 * buffer has not been revoked, and cancel_revoke
12593 * RevokeValid set, Revoked set:
12594 * buffer has been revoked.
12597 static kmem_cache_t *revoke_record_cache;
12598 static kmem_cache_t *revoke_table_cache;
12600 /* Each revoke record represents one single revoked block. During
12601 journal replay, this involves recording the transaction ID of the
12602 last transaction to revoke this block. */
12604 struct jbd_revoke_record_s
12606 struct list_head hash;
12607 tid_t sequence; /* Used for recovery only */
12608 unsigned long blocknr;
12612 /* The revoke table is just a simple hash table of revoke records. */
12613 struct jbd_revoke_table_s
12615 /* It is conceivable that we might want a larger hash table
12616 * for recovery. Must be a power of two. */
12619 struct list_head *hash_table;
12623 /* Utility functions to maintain the revoke table */
12625 /* Borrowed from buffer.c: this is a tried and tested block hash function */
12626 static inline int hash(journal_t *journal, unsigned long block)
12628 struct jbd_revoke_table_s *table = journal->j_revoke;
12629 int hash_shift = table->hash_shift;
12631 return ((block << (hash_shift - 6)) ^
12633 (block << (hash_shift - 12))) & (table->hash_size - 1);
12636 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
12639 struct list_head *hash_list;
12640 struct jbd_revoke_record_s *record;
12642 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
12646 record->sequence = seq;
12647 record->blocknr = blocknr;
12648 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
12649 list_add(&record->hash, hash_list);
12656 /* Find a revoke record in the journal's hash table. */
12658 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
12659 unsigned long blocknr)
12661 struct list_head *hash_list;
12662 struct jbd_revoke_record_s *record;
12664 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
12666 record = (struct jbd_revoke_record_s *) hash_list->next;
12667 while (&(record->hash) != hash_list) {
12668 if (record->blocknr == blocknr)
12670 record = (struct jbd_revoke_record_s *) record->hash.next;
12675 int journal_init_revoke_caches(void)
12677 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
12678 if (revoke_record_cache == 0)
12681 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
12682 if (revoke_table_cache == 0) {
12683 do_cache_destroy(revoke_record_cache);
12684 revoke_record_cache = NULL;
12690 void journal_destroy_revoke_caches(void)
12692 do_cache_destroy(revoke_record_cache);
12693 revoke_record_cache = 0;
12694 do_cache_destroy(revoke_table_cache);
12695 revoke_table_cache = 0;
12698 /* Initialise the revoke table for a given journal to a given size. */
12700 int journal_init_revoke(journal_t *journal, int hash_size)
12704 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
12705 if (!journal->j_revoke)
12708 /* Check that the hash_size is a power of two */
12709 journal->j_revoke->hash_size = hash_size;
12713 while((tmp >>= 1UL) != 0UL)
12715 journal->j_revoke->hash_shift = shift;
12717 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
12718 if (!journal->j_revoke->hash_table) {
12719 free(journal->j_revoke);
12720 journal->j_revoke = NULL;
12724 for (tmp = 0; tmp < hash_size; tmp++)
12725 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
12730 /* Destoy a journal's revoke table. The table must already be empty! */
12732 void journal_destroy_revoke(journal_t *journal)
12734 struct jbd_revoke_table_s *table;
12735 struct list_head *hash_list;
12738 table = journal->j_revoke;
12742 for (i=0; i<table->hash_size; i++) {
12743 hash_list = &table->hash_table[i];
12746 free(table->hash_table);
12748 journal->j_revoke = NULL;
12752 * Revoke support for recovery.
12754 * Recovery needs to be able to:
12756 * record all revoke records, including the tid of the latest instance
12757 * of each revoke in the journal
12759 * check whether a given block in a given transaction should be replayed
12760 * (ie. has not been revoked by a revoke record in that or a subsequent
12763 * empty the revoke table after recovery.
12767 * First, setting revoke records. We create a new revoke record for
12768 * every block ever revoked in the log as we scan it for recovery, and
12769 * we update the existing records if we find multiple revokes for a
12773 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
12776 struct jbd_revoke_record_s *record;
12778 record = find_revoke_record(journal, blocknr);
12780 /* If we have multiple occurences, only record the
12781 * latest sequence number in the hashed record */
12782 if (tid_gt(sequence, record->sequence))
12783 record->sequence = sequence;
12786 return insert_revoke_hash(journal, blocknr, sequence);
12790 * Test revoke records. For a given block referenced in the log, has
12791 * that block been revoked? A revoke record with a given transaction
12792 * sequence number revokes all blocks in that transaction and earlier
12793 * ones, but later transactions still need replayed.
12796 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
12799 struct jbd_revoke_record_s *record;
12801 record = find_revoke_record(journal, blocknr);
12804 if (tid_gt(sequence, record->sequence))
12810 * Finally, once recovery is over, we need to clear the revoke table so
12811 * that it can be reused by the running filesystem.
12814 void journal_clear_revoke(journal_t *journal)
12817 struct list_head *hash_list;
12818 struct jbd_revoke_record_s *record;
12819 struct jbd_revoke_table_s *revoke_var;
12821 revoke_var = journal->j_revoke;
12823 for (i = 0; i < revoke_var->hash_size; i++) {
12824 hash_list = &revoke_var->hash_table[i];
12825 while (!list_empty(hash_list)) {
12826 record = (struct jbd_revoke_record_s*) hash_list->next;
12827 list_del(&record->hash);
12834 * e2fsck.c - superblock checks
12837 #define MIN_CHECK 1
12838 #define MAX_CHECK 2
12840 static void check_super_value(e2fsck_t ctx, const char *descr,
12841 unsigned long value, int flags,
12842 unsigned long min_val, unsigned long max_val)
12844 struct problem_context pctx;
12846 if (((flags & MIN_CHECK) && (value < min_val)) ||
12847 ((flags & MAX_CHECK) && (value > max_val))) {
12848 clear_problem_context(&pctx);
12851 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12852 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12857 * This routine may get stubbed out in special compilations of the
12860 #ifndef EXT2_SPECIAL_DEVICE_SIZE
12861 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
12863 return (ext2fs_get_device_size(ctx->filesystem_name,
12864 EXT2_BLOCK_SIZE(ctx->fs->super),
12865 &ctx->num_blocks));
12870 * helper function to release an inode
12872 struct process_block_struct {
12875 struct problem_context *pctx;
12877 int truncate_offset;
12878 e2_blkcnt_t truncate_block;
12879 int truncated_blocks;
12884 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
12885 e2_blkcnt_t blockcnt,
12886 blk_t ref_blk FSCK_ATTR((unused)),
12887 int ref_offset FSCK_ATTR((unused)),
12890 struct process_block_struct *pb;
12892 struct problem_context *pctx;
12893 blk_t blk = *block_nr;
12896 pb = (struct process_block_struct *) priv_data;
12901 pctx->blkcount = blockcnt;
12903 if (HOLE_BLKADDR(blk))
12906 if ((blk < fs->super->s_first_data_block) ||
12907 (blk >= fs->super->s_blocks_count)) {
12908 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
12911 return BLOCK_ABORT;
12914 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
12915 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
12920 * If we are deleting an orphan, then we leave the fields alone.
12921 * If we are truncating an orphan, then update the inode fields
12922 * and clean up any partial block data.
12924 if (pb->truncating) {
12926 * We only remove indirect blocks if they are
12927 * completely empty.
12929 if (blockcnt < 0) {
12933 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
12938 limit = fs->blocksize >> 2;
12939 for (i = 0, bp = (blk_t *) pb->buf;
12940 i < limit; i++, bp++)
12945 * We don't remove direct blocks until we've reached
12946 * the truncation block.
12948 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
12951 * If part of the last block needs truncating, we do
12954 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
12955 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
12959 memset(pb->buf + pb->truncate_offset, 0,
12960 fs->blocksize - pb->truncate_offset);
12961 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
12966 pb->truncated_blocks++;
12968 retval |= BLOCK_CHANGED;
12971 ext2fs_block_alloc_stats(fs, blk, -1);
12976 * This function releases an inode. Returns 1 if an inconsistency was
12977 * found. If the inode has a link count, then it is being truncated and
12980 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
12981 struct ext2_inode *inode, char *block_buf,
12982 struct problem_context *pctx)
12984 struct process_block_struct pb;
12985 ext2_filsys fs = ctx->fs;
12989 if (!ext2fs_inode_has_valid_blocks(inode))
12992 pb.buf = block_buf + 3 * ctx->fs->blocksize;
12997 if (inode->i_links_count) {
12999 pb.truncate_block = (e2_blkcnt_t)
13000 ((((long long)inode->i_size_high << 32) +
13001 inode->i_size + fs->blocksize - 1) /
13003 pb.truncate_offset = inode->i_size % fs->blocksize;
13006 pb.truncate_block = 0;
13007 pb.truncate_offset = 0;
13009 pb.truncated_blocks = 0;
13010 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
13011 block_buf, release_inode_block, &pb);
13013 com_err("release_inode_blocks", retval,
13014 _("while calling ext2fs_block_iterate for inode %d"),
13021 /* Refresh the inode since ext2fs_block_iterate may have changed it */
13022 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
13024 if (pb.truncated_blocks)
13025 inode->i_blocks -= pb.truncated_blocks *
13026 (fs->blocksize / 512);
13028 if (inode->i_file_acl) {
13029 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
13030 block_buf, -1, &count);
13031 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
13036 com_err("release_inode_blocks", retval,
13037 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
13042 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
13043 inode->i_file_acl = 0;
13049 * This function releases all of the orphan inodes. It returns 1 if
13050 * it hit some error, and 0 on success.
13052 static int release_orphan_inodes(e2fsck_t ctx)
13054 ext2_filsys fs = ctx->fs;
13055 ext2_ino_t ino, next_ino;
13056 struct ext2_inode inode;
13057 struct problem_context pctx;
13060 if ((ino = fs->super->s_last_orphan) == 0)
13064 * Win or lose, we won't be using the head of the orphan inode
13067 fs->super->s_last_orphan = 0;
13068 ext2fs_mark_super_dirty(fs);
13071 * If the filesystem contains errors, don't run the orphan
13072 * list, since the orphan list can't be trusted; and we're
13073 * going to be running a full e2fsck run anyway...
13075 if (fs->super->s_state & EXT2_ERROR_FS)
13078 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
13079 (ino > fs->super->s_inodes_count)) {
13080 clear_problem_context(&pctx);
13082 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
13086 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
13087 "block iterate buffer");
13088 e2fsck_read_bitmaps(ctx);
13091 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
13092 clear_problem_context(&pctx);
13094 pctx.inode = &inode;
13095 pctx.str = inode.i_links_count ? _("Truncating") :
13098 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
13100 next_ino = inode.i_dtime;
13102 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
13103 (next_ino > fs->super->s_inodes_count))) {
13104 pctx.ino = next_ino;
13105 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
13109 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
13112 if (!inode.i_links_count) {
13113 ext2fs_inode_alloc_stats2(fs, ino, -1,
13114 LINUX_S_ISDIR(inode.i_mode));
13115 inode.i_dtime = time(0);
13119 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
13122 ext2fs_free_mem(&block_buf);
13125 ext2fs_free_mem(&block_buf);
13130 * Check the resize inode to make sure it is sane. We check both for
13131 * the case where on-line resizing is not enabled (in which case the
13132 * resize inode should be cleared) as well as the case where on-line
13133 * resizing is enabled.
13135 static void check_resize_inode(e2fsck_t ctx)
13137 ext2_filsys fs = ctx->fs;
13138 struct ext2_inode inode;
13139 struct problem_context pctx;
13140 int i, j, gdt_off, ind_off;
13141 blk_t blk, pblk, expect;
13142 __u32 *dind_buf = 0, *ind_buf;
13145 clear_problem_context(&pctx);
13148 * If the resize inode feature isn't set, then
13149 * s_reserved_gdt_blocks must be zero.
13151 if (!(fs->super->s_feature_compat &
13152 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
13153 if (fs->super->s_reserved_gdt_blocks) {
13154 pctx.num = fs->super->s_reserved_gdt_blocks;
13155 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
13157 fs->super->s_reserved_gdt_blocks = 0;
13158 ext2fs_mark_super_dirty(fs);
13163 /* Read the resize inode */
13164 pctx.ino = EXT2_RESIZE_INO;
13165 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
13167 if (fs->super->s_feature_compat &
13168 EXT2_FEATURE_COMPAT_RESIZE_INODE)
13169 ctx->flags |= E2F_FLAG_RESIZE_INODE;
13174 * If the resize inode feature isn't set, check to make sure
13175 * the resize inode is cleared; then we're done.
13177 if (!(fs->super->s_feature_compat &
13178 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
13179 for (i=0; i < EXT2_N_BLOCKS; i++) {
13180 if (inode.i_block[i])
13183 if ((i < EXT2_N_BLOCKS) &&
13184 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
13185 memset(&inode, 0, sizeof(inode));
13186 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
13193 * The resize inode feature is enabled; check to make sure the
13194 * only block in use is the double indirect block
13196 blk = inode.i_block[EXT2_DIND_BLOCK];
13197 for (i=0; i < EXT2_N_BLOCKS; i++) {
13198 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
13201 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
13202 !(inode.i_mode & LINUX_S_IFREG) ||
13203 (blk < fs->super->s_first_data_block ||
13204 blk >= fs->super->s_blocks_count)) {
13205 resize_inode_invalid:
13206 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
13207 memset(&inode, 0, sizeof(inode));
13208 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
13210 ctx->flags |= E2F_FLAG_RESIZE_INODE;
13212 if (!(ctx->options & E2F_OPT_READONLY)) {
13213 fs->super->s_state &= ~EXT2_VALID_FS;
13214 ext2fs_mark_super_dirty(fs);
13218 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
13219 "resize dind buffer");
13220 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
13222 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
13224 goto resize_inode_invalid;
13226 gdt_off = fs->desc_blocks;
13227 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
13228 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
13229 i++, gdt_off++, pblk++) {
13230 gdt_off %= fs->blocksize/4;
13231 if (dind_buf[gdt_off] != pblk)
13232 goto resize_inode_invalid;
13233 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
13235 goto resize_inode_invalid;
13237 for (j = 1; j < fs->group_desc_count; j++) {
13238 if (!ext2fs_bg_has_super(fs, j))
13240 expect = pblk + (j * fs->super->s_blocks_per_group);
13241 if (ind_buf[ind_off] != expect)
13242 goto resize_inode_invalid;
13248 ext2fs_free_mem(&dind_buf);
13252 static void check_super_block(e2fsck_t ctx)
13254 ext2_filsys fs = ctx->fs;
13255 blk_t first_block, last_block;
13256 struct ext2_super_block *sb = fs->super;
13257 struct ext2_group_desc *gd;
13258 blk_t blocks_per_group = fs->super->s_blocks_per_group;
13260 int inodes_per_block;
13265 struct problem_context pctx;
13266 __u32 free_blocks = 0, free_inodes = 0;
13268 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
13269 ipg_max = inodes_per_block * (blocks_per_group - 4);
13270 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
13271 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
13272 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
13273 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
13274 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
13276 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13277 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
13278 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13279 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
13280 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
13281 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
13283 clear_problem_context(&pctx);
13286 * Verify the super block constants...
13288 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
13290 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
13292 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
13293 MAX_CHECK, 0, sb->s_blocks_count);
13294 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
13295 MIN_CHECK | MAX_CHECK, 0,
13296 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
13297 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
13298 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
13299 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
13300 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
13302 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
13303 MIN_CHECK | MAX_CHECK, 8, bpg_max);
13304 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
13305 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
13306 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
13307 MAX_CHECK, 0, sb->s_blocks_count / 2);
13308 check_super_value(ctx, "reserved_gdt_blocks",
13309 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
13311 inode_size = EXT2_INODE_SIZE(sb);
13312 check_super_value(ctx, "inode_size",
13313 inode_size, MIN_CHECK | MAX_CHECK,
13314 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
13315 if (inode_size & (inode_size - 1)) {
13316 pctx.num = inode_size;
13317 pctx.str = "inode_size";
13318 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13319 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13323 if (!ctx->num_blocks) {
13324 pctx.errcode = e2fsck_get_device_size(ctx);
13325 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
13326 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
13327 ctx->flags |= E2F_FLAG_ABORT;
13330 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
13331 (ctx->num_blocks < sb->s_blocks_count)) {
13332 pctx.blk = sb->s_blocks_count;
13333 pctx.blk2 = ctx->num_blocks;
13334 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
13335 ctx->flags |= E2F_FLAG_ABORT;
13341 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
13342 pctx.blk = EXT2_BLOCK_SIZE(sb);
13343 pctx.blk2 = EXT2_FRAG_SIZE(sb);
13344 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
13345 ctx->flags |= E2F_FLAG_ABORT;
13349 should_be = sb->s_frags_per_group >>
13350 (sb->s_log_block_size - sb->s_log_frag_size);
13351 if (sb->s_blocks_per_group != should_be) {
13352 pctx.blk = sb->s_blocks_per_group;
13353 pctx.blk2 = should_be;
13354 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
13355 ctx->flags |= E2F_FLAG_ABORT;
13359 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
13360 if (sb->s_first_data_block != should_be) {
13361 pctx.blk = sb->s_first_data_block;
13362 pctx.blk2 = should_be;
13363 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
13364 ctx->flags |= E2F_FLAG_ABORT;
13368 should_be = sb->s_inodes_per_group * fs->group_desc_count;
13369 if (sb->s_inodes_count != should_be) {
13370 pctx.ino = sb->s_inodes_count;
13371 pctx.ino2 = should_be;
13372 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
13373 sb->s_inodes_count = should_be;
13374 ext2fs_mark_super_dirty(fs);
13379 * Verify the group descriptors....
13381 first_block = sb->s_first_data_block;
13382 last_block = first_block + blocks_per_group;
13384 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
13387 if (i == fs->group_desc_count - 1)
13388 last_block = sb->s_blocks_count;
13389 if ((gd->bg_block_bitmap < first_block) ||
13390 (gd->bg_block_bitmap >= last_block)) {
13391 pctx.blk = gd->bg_block_bitmap;
13392 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
13393 gd->bg_block_bitmap = 0;
13395 if (gd->bg_block_bitmap == 0) {
13396 ctx->invalid_block_bitmap_flag[i]++;
13397 ctx->invalid_bitmaps++;
13399 if ((gd->bg_inode_bitmap < first_block) ||
13400 (gd->bg_inode_bitmap >= last_block)) {
13401 pctx.blk = gd->bg_inode_bitmap;
13402 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
13403 gd->bg_inode_bitmap = 0;
13405 if (gd->bg_inode_bitmap == 0) {
13406 ctx->invalid_inode_bitmap_flag[i]++;
13407 ctx->invalid_bitmaps++;
13409 if ((gd->bg_inode_table < first_block) ||
13410 ((gd->bg_inode_table +
13411 fs->inode_blocks_per_group - 1) >= last_block)) {
13412 pctx.blk = gd->bg_inode_table;
13413 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
13414 gd->bg_inode_table = 0;
13416 if (gd->bg_inode_table == 0) {
13417 ctx->invalid_inode_table_flag[i]++;
13418 ctx->invalid_bitmaps++;
13420 free_blocks += gd->bg_free_blocks_count;
13421 free_inodes += gd->bg_free_inodes_count;
13422 first_block += sb->s_blocks_per_group;
13423 last_block += sb->s_blocks_per_group;
13425 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
13426 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
13427 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
13428 ext2fs_unmark_valid(fs);
13433 * Update the global counts from the block group counts. This
13434 * is needed for an experimental patch which eliminates
13435 * locking the entire filesystem when allocating blocks or
13436 * inodes; if the filesystem is not unmounted cleanly, the
13437 * global counts may not be accurate.
13439 if ((free_blocks != sb->s_free_blocks_count) ||
13440 (free_inodes != sb->s_free_inodes_count)) {
13441 if (ctx->options & E2F_OPT_READONLY)
13442 ext2fs_unmark_valid(fs);
13444 sb->s_free_blocks_count = free_blocks;
13445 sb->s_free_inodes_count = free_inodes;
13446 ext2fs_mark_super_dirty(fs);
13450 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
13451 (sb->s_free_inodes_count > sb->s_inodes_count))
13452 ext2fs_unmark_valid(fs);
13456 * If we have invalid bitmaps, set the error state of the
13459 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
13460 sb->s_state &= ~EXT2_VALID_FS;
13461 ext2fs_mark_super_dirty(fs);
13464 clear_problem_context(&pctx);
13466 #ifndef EXT2_SKIP_UUID
13468 * If the UUID field isn't assigned, assign it.
13470 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
13471 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
13472 uuid_generate(sb->s_uuid);
13473 ext2fs_mark_super_dirty(fs);
13474 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13480 * For the Hurd, check to see if the filetype option is set,
13481 * since it doesn't support it.
13483 if (!(ctx->options & E2F_OPT_READONLY) &&
13484 fs->super->s_creator_os == EXT2_OS_HURD &&
13485 (fs->super->s_feature_incompat &
13486 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
13487 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
13488 fs->super->s_feature_incompat &=
13489 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
13490 ext2fs_mark_super_dirty(fs);
13496 * If we have any of the compatibility flags set, we need to have a
13497 * revision 1 filesystem. Most kernels will not check the flags on
13498 * a rev 0 filesystem and we may have corruption issues because of
13499 * the incompatible changes to the filesystem.
13501 if (!(ctx->options & E2F_OPT_READONLY) &&
13502 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
13503 (fs->super->s_feature_compat ||
13504 fs->super->s_feature_ro_compat ||
13505 fs->super->s_feature_incompat) &&
13506 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
13507 ext2fs_update_dynamic_rev(fs);
13508 ext2fs_mark_super_dirty(fs);
13511 check_resize_inode(ctx);
13514 * Clean up any orphan inodes, if present.
13516 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
13517 fs->super->s_state &= ~EXT2_VALID_FS;
13518 ext2fs_mark_super_dirty(fs);
13522 * Move the ext3 journal file, if necessary.
13524 e2fsck_move_ext3_journal(ctx);
13529 * swapfs.c --- byte-swap an ext2 filesystem
13532 #ifdef ENABLE_SWAPFS
13534 struct swap_block_struct {
13539 struct ext2_inode *inode;
13543 * This is a helper function for block_iterate. We mark all of the
13544 * indirect and direct blocks as changed, so that block_iterate will
13547 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
13552 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
13554 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
13555 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
13557 sb->errcode = retval;
13558 return BLOCK_ABORT;
13560 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
13562 sb->errcode = retval;
13563 return BLOCK_ABORT;
13566 if (blockcnt >= 0) {
13567 if (blockcnt < EXT2_NDIR_BLOCKS)
13569 return BLOCK_CHANGED;
13571 if (blockcnt == BLOCK_COUNT_IND) {
13572 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
13574 return BLOCK_CHANGED;
13576 if (blockcnt == BLOCK_COUNT_DIND) {
13577 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
13579 return BLOCK_CHANGED;
13581 if (blockcnt == BLOCK_COUNT_TIND) {
13582 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
13584 return BLOCK_CHANGED;
13586 return BLOCK_CHANGED;
13590 * This function is responsible for byte-swapping all of the indirect,
13591 * block pointers. It is also responsible for byte-swapping directories.
13593 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
13594 struct ext2_inode *inode)
13597 struct swap_block_struct sb;
13601 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
13604 if (LINUX_S_ISDIR(inode->i_mode))
13607 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
13610 com_err("swap_inode_blocks", retval,
13611 _("while calling ext2fs_block_iterate"));
13612 ctx->flags |= E2F_FLAG_ABORT;
13616 com_err("swap_inode_blocks", sb.errcode,
13617 _("while calling iterator function"));
13618 ctx->flags |= E2F_FLAG_ABORT;
13623 static void swap_inodes(e2fsck_t ctx)
13625 ext2_filsys fs = ctx->fs;
13628 ext2_ino_t ino = 1;
13629 char *buf, *block_buf;
13631 struct ext2_inode * inode;
13633 e2fsck_use_inode_shortcuts(ctx, 1);
13635 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
13638 com_err("swap_inodes", retval,
13639 _("while allocating inode buffer"));
13640 ctx->flags |= E2F_FLAG_ABORT;
13643 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
13644 "block interate buffer");
13645 for (group = 0; group < fs->group_desc_count; group++) {
13646 retval = io_channel_read_blk(fs->io,
13647 fs->group_desc[group].bg_inode_table,
13648 fs->inode_blocks_per_group, buf);
13650 com_err("swap_inodes", retval,
13651 _("while reading inode table (group %d)"),
13653 ctx->flags |= E2F_FLAG_ABORT;
13656 inode = (struct ext2_inode *) buf;
13657 for (i=0; i < fs->super->s_inodes_per_group;
13658 i++, ino++, inode++) {
13659 ctx->stashed_ino = ino;
13660 ctx->stashed_inode = inode;
13662 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
13663 ext2fs_swap_inode(fs, inode, inode, 0);
13666 * Skip deleted files.
13668 if (inode->i_links_count == 0)
13671 if (LINUX_S_ISDIR(inode->i_mode) ||
13672 ((inode->i_block[EXT2_IND_BLOCK] ||
13673 inode->i_block[EXT2_DIND_BLOCK] ||
13674 inode->i_block[EXT2_TIND_BLOCK]) &&
13675 ext2fs_inode_has_valid_blocks(inode)))
13676 swap_inode_blocks(ctx, ino, block_buf, inode);
13678 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13681 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
13682 ext2fs_swap_inode(fs, inode, inode, 1);
13684 retval = io_channel_write_blk(fs->io,
13685 fs->group_desc[group].bg_inode_table,
13686 fs->inode_blocks_per_group, buf);
13688 com_err("swap_inodes", retval,
13689 _("while writing inode table (group %d)"),
13691 ctx->flags |= E2F_FLAG_ABORT;
13695 ext2fs_free_mem(&buf);
13696 ext2fs_free_mem(&block_buf);
13697 e2fsck_use_inode_shortcuts(ctx, 0);
13698 ext2fs_flush_icache(fs);
13701 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
13703 * On the PowerPC, the big-endian variant of the ext2 filesystem
13704 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
13705 * of each word. Thus a bitmap with only bit 0 set would be, as
13706 * a string of bytes, 00 00 00 01 00 ...
13707 * To cope with this, we byte-reverse each word of a bitmap if
13708 * we have a big-endian filesystem, that is, if we are *not*
13709 * byte-swapping other word-sized numbers.
13711 #define EXT2_BIG_ENDIAN_BITMAPS
13714 #ifdef EXT2_BIG_ENDIAN_BITMAPS
13715 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
13717 __u32 *p = (__u32 *) bmap->bitmap;
13718 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
13720 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
13721 *p = ext2fs_swab32(*p);
13726 #ifdef ENABLE_SWAPFS
13727 static void swap_filesys(e2fsck_t ctx)
13729 ext2_filsys fs = ctx->fs;
13730 #ifdef RESOURCE_TRACK
13731 struct resource_track rtrack;
13733 init_resource_track(&rtrack);
13736 if (!(ctx->options & E2F_OPT_PREEN))
13737 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
13740 mtrace_print("Byte swap");
13743 if (fs->super->s_mnt_count) {
13744 fprintf(stderr, _("%s: the filesystem must be freshly "
13745 "checked using fsck\n"
13746 "and not mounted before trying to "
13747 "byte-swap it.\n"), ctx->device_name);
13748 ctx->flags |= E2F_FLAG_ABORT;
13751 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
13752 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
13753 EXT2_FLAG_SWAP_BYTES_WRITE);
13754 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
13756 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
13757 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
13760 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13762 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
13763 fs->flags |= EXT2_FLAG_SWAP_BYTES;
13764 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
13765 EXT2_FLAG_SWAP_BYTES_WRITE);
13767 #ifdef EXT2_BIG_ENDIAN_BITMAPS
13768 e2fsck_read_bitmaps(ctx);
13769 ext2fs_swap_bitmap(fs->inode_map);
13770 ext2fs_swap_bitmap(fs->block_map);
13771 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
13773 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13775 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13777 #ifdef RESOURCE_TRACK
13778 if (ctx->options & E2F_OPT_TIME2)
13779 print_resource_track(_("Byte swap"), &rtrack);
13782 #endif /* ENABLE_SWAPFS */
13787 * util.c --- miscellaneous utilities
13792 void fatal_error(e2fsck_t ctx, const char *msg)
13795 fprintf (stderr, "e2fsck: %s\n", msg);
13796 if (ctx->fs && ctx->fs->io) {
13797 if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
13798 io_channel_flush(ctx->fs->io);
13800 fprintf(stderr, "e2fsck: io manager magic bad!\n");
13802 ctx->flags |= E2F_FLAG_ABORT;
13803 if (ctx->flags & E2F_FLAG_SETJMP_OK)
13804 longjmp(ctx->abort_loc, 1);
13809 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
13810 const char *description)
13815 #ifdef DEBUG_ALLOCATE_MEMORY
13816 printf("Allocating %d bytes for %s...\n", size, description);
13818 ret = malloc(size);
13820 sprintf(buf, "Can't allocate %s\n", description);
13821 fatal_error(ctx, buf);
13823 memset(ret, 0, size);
13827 static char *string_copy(const char *str, int len)
13835 ret = malloc(len+1);
13837 strncpy(ret, str, len);
13843 #ifndef HAVE_CONIO_H
13844 static int read_a_char(void)
13851 if (e2fsck_global_ctx &&
13852 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
13855 r = read(0, &c, 1);
13865 static int ask_yn(const char * string, int def)
13868 const char *defstr;
13869 static const char short_yes[] = "yY";
13870 static const char short_no[] = "nN";
13872 #ifdef HAVE_TERMIOS_H
13873 struct termios termios, tmp;
13875 tcgetattr (0, &termios);
13877 tmp.c_lflag &= ~(ICANON | ECHO);
13878 tmp.c_cc[VMIN] = 1;
13879 tmp.c_cc[VTIME] = 0;
13880 tcsetattr (0, TCSANOW, &tmp);
13889 printf("%s%s? ", string, defstr);
13892 if ((c = read_a_char()) == EOF)
13895 #ifdef HAVE_TERMIOS_H
13896 tcsetattr (0, TCSANOW, &termios);
13898 if (e2fsck_global_ctx &&
13899 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
13901 longjmp(e2fsck_global_ctx->abort_loc, 1);
13903 puts(_("cancelled!\n"));
13906 if (strchr(short_yes, (char) c)) {
13910 else if (strchr(short_no, (char) c)) {
13914 else if ((c == ' ' || c == '\n') && (def != -1))
13921 #ifdef HAVE_TERMIOS_H
13922 tcsetattr (0, TCSANOW, &termios);
13927 int ask (e2fsck_t ctx, const char * string, int def)
13929 if (ctx->options & E2F_OPT_NO) {
13930 printf (_("%s? no\n\n"), string);
13933 if (ctx->options & E2F_OPT_YES) {
13934 printf (_("%s? yes\n\n"), string);
13937 if (ctx->options & E2F_OPT_PREEN) {
13938 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
13941 return ask_yn(string, def);
13944 void e2fsck_read_bitmaps(e2fsck_t ctx)
13946 ext2_filsys fs = ctx->fs;
13949 if (ctx->invalid_bitmaps) {
13950 com_err(ctx->program_name, 0,
13951 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
13953 fatal_error(ctx, 0);
13956 ehandler_operation(_("reading inode and block bitmaps"));
13957 retval = ext2fs_read_bitmaps(fs);
13958 ehandler_operation(0);
13960 com_err(ctx->program_name, retval,
13961 _("while retrying to read bitmaps for %s"),
13963 fatal_error(ctx, 0);
13967 static void e2fsck_write_bitmaps(e2fsck_t ctx)
13969 ext2_filsys fs = ctx->fs;
13972 if (ext2fs_test_bb_dirty(fs)) {
13973 ehandler_operation(_("writing block bitmaps"));
13974 retval = ext2fs_write_block_bitmap(fs);
13975 ehandler_operation(0);
13977 com_err(ctx->program_name, retval,
13978 _("while retrying to write block bitmaps for %s"),
13980 fatal_error(ctx, 0);
13984 if (ext2fs_test_ib_dirty(fs)) {
13985 ehandler_operation(_("writing inode bitmaps"));
13986 retval = ext2fs_write_inode_bitmap(fs);
13987 ehandler_operation(0);
13989 com_err(ctx->program_name, retval,
13990 _("while retrying to write inode bitmaps for %s"),
13992 fatal_error(ctx, 0);
13997 void preenhalt(e2fsck_t ctx)
13999 ext2_filsys fs = ctx->fs;
14001 if (!(ctx->options & E2F_OPT_PREEN))
14003 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
14004 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
14007 fs->super->s_state |= EXT2_ERROR_FS;
14008 ext2fs_mark_super_dirty(fs);
14011 exit(EXIT_UNCORRECTED);
14014 #ifdef RESOURCE_TRACK
14015 void init_resource_track(struct resource_track *track)
14017 #ifdef HAVE_GETRUSAGE
14021 track->brk_start = sbrk(0);
14022 gettimeofday(&track->time_start, 0);
14023 #ifdef HAVE_GETRUSAGE
14025 memset(&r, 0, sizeof(struct rusage));
14027 getrusage(RUSAGE_SELF, &r);
14028 track->user_start = r.ru_utime;
14029 track->system_start = r.ru_stime;
14031 track->user_start.tv_sec = track->user_start.tv_usec = 0;
14032 track->system_start.tv_sec = track->system_start.tv_usec = 0;
14036 static _INLINE_ float timeval_subtract(struct timeval *tv1,
14037 struct timeval *tv2)
14039 return ((tv1->tv_sec - tv2->tv_sec) +
14040 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
14043 void print_resource_track(const char *desc, struct resource_track *track)
14045 #ifdef HAVE_GETRUSAGE
14048 #ifdef HAVE_MALLINFO
14049 struct mallinfo malloc_info;
14051 struct timeval time_end;
14053 gettimeofday(&time_end, 0);
14056 printf("%s: ", desc);
14058 #ifdef HAVE_MALLINFO
14059 #define kbytes(x) (((x) + 1023) / 1024)
14061 malloc_info = mallinfo();
14062 printf(_("Memory used: %dk/%dk (%dk/%dk), "),
14063 kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
14064 kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
14066 printf(_("Memory used: %d, "),
14067 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
14069 #ifdef HAVE_GETRUSAGE
14070 getrusage(RUSAGE_SELF, &r);
14072 printf(_("time: %5.2f/%5.2f/%5.2f\n"),
14073 timeval_subtract(&time_end, &track->time_start),
14074 timeval_subtract(&r.ru_utime, &track->user_start),
14075 timeval_subtract(&r.ru_stime, &track->system_start));
14077 printf(_("elapsed time: %6.3f\n"),
14078 timeval_subtract(&time_end, &track->time_start));
14081 #endif /* RESOURCE_TRACK */
14083 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
14084 struct ext2_inode * inode, const char *proc)
14088 retval = ext2fs_read_inode(ctx->fs, ino, inode);
14090 com_err("ext2fs_read_inode", retval,
14091 _("while reading inode %ld in %s"), ino, proc);
14092 fatal_error(ctx, 0);
14096 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
14097 struct ext2_inode * inode, int bufsize,
14102 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
14104 com_err("ext2fs_write_inode", retval,
14105 _("while writing inode %ld in %s"), ino, proc);
14106 fatal_error(ctx, 0);
14110 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
14111 struct ext2_inode * inode, const char *proc)
14115 retval = ext2fs_write_inode(ctx->fs, ino, inode);
14117 com_err("ext2fs_write_inode", retval,
14118 _("while writing inode %ld in %s"), ino, proc);
14119 fatal_error(ctx, 0);
14124 void mtrace_print(char *mesg)
14126 FILE *malloc_get_mallstream();
14127 FILE *f = malloc_get_mallstream();
14130 fprintf(f, "============= %s\n", mesg);
14134 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
14135 io_manager manager)
14137 struct ext2_super_block *sb;
14138 io_channel io = NULL;
14141 blk_t superblock, ret_sb = 8193;
14143 if (fs && fs->super) {
14144 ret_sb = (fs->super->s_blocks_per_group +
14145 fs->super->s_first_data_block);
14147 ctx->superblock = ret_sb;
14148 ctx->blocksize = fs->blocksize;
14154 if (ctx->blocksize) {
14155 ret_sb = ctx->blocksize * 8;
14156 if (ctx->blocksize == 1024)
14158 ctx->superblock = ret_sb;
14161 ctx->superblock = ret_sb;
14162 ctx->blocksize = 1024;
14165 if (!name || !manager)
14168 if (manager->open(name, 0, &io) != 0)
14171 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
14173 sb = (struct ext2_super_block *) buf;
14175 for (blocksize = EXT2_MIN_BLOCK_SIZE;
14176 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
14177 superblock = blocksize*8;
14178 if (blocksize == 1024)
14180 io_channel_set_blksize(io, blocksize);
14181 if (io_channel_read_blk(io, superblock,
14182 -SUPERBLOCK_SIZE, buf))
14184 #ifdef EXT2FS_ENABLE_SWAPFS
14185 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
14186 ext2fs_swap_super(sb);
14188 if (sb->s_magic == EXT2_SUPER_MAGIC) {
14189 ret_sb = superblock;
14191 ctx->superblock = superblock;
14192 ctx->blocksize = blocksize;
14200 io_channel_close(io);
14201 ext2fs_free_mem(&buf);
14207 * This function runs through the e2fsck passes and calls them all,
14208 * returning restart, abort, or cancel as necessary...
14210 typedef void (*pass_t)(e2fsck_t ctx);
14212 static const pass_t e2fsck_passes[] = {
14213 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
14216 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
14218 static int e2fsck_run(e2fsck_t ctx)
14221 pass_t e2fsck_pass;
14223 if (setjmp(ctx->abort_loc)) {
14224 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
14225 return (ctx->flags & E2F_FLAG_RUN_RETURN);
14227 ctx->flags |= E2F_FLAG_SETJMP_OK;
14229 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
14230 if (ctx->flags & E2F_FLAG_RUN_RETURN)
14234 (void) (ctx->progress)(ctx, 0, 0, 0);
14236 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
14238 if (ctx->flags & E2F_FLAG_RUN_RETURN)
14239 return (ctx->flags & E2F_FLAG_RUN_RETURN);
14245 * unix.c - The unix-specific code for e2fsck
14249 /* Command line options */
14251 #ifdef ENABLE_SWAPFS
14252 static int normalize_swapfs;
14254 static int cflag; /* check disk */
14255 static int show_version_only;
14256 static int verbose;
14258 static int replace_bad_blocks;
14259 static int keep_bad_blocks;
14260 static char *bad_blocks_file;
14262 #ifdef __CONFIG_JBD_DEBUG__E2FS /* Enabled by configure --enable-jfs-debug */
14263 int journal_enable_debug = -1;
14267 static void usage(e2fsck_t ctx)
14270 _("Usage: %s [-panyrcdfvstDFSV] [-b superblock] [-B blocksize]\n"
14271 "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
14272 "\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
14273 "\t\t[-E extended-options] device\n"),
14274 ctx->program_name);
14276 fprintf(stderr, _("\nEmergency help:\n"
14277 " -p Automatic repair (no questions)\n"
14278 " -n Make no changes to the filesystem\n"
14279 " -y Assume \"yes\" to all questions\n"
14280 " -c Check for bad blocks and add them to the badblock list\n"
14281 " -f Force checking even if filesystem is marked clean\n"));
14282 fprintf(stderr, _(""
14284 " -b superblock Use alternative superblock\n"
14285 " -B blocksize Force blocksize when looking for superblock\n"
14286 " -j external_journal Set location of the external journal\n"
14287 " -l bad_blocks_file Add to badblocks list\n"
14288 " -L bad_blocks_file Set badblocks list\n"
14295 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
14297 static void show_stats(e2fsck_t ctx)
14299 ext2_filsys fs = ctx->fs;
14300 int inodes, inodes_used, blocks, blocks_used;
14302 int num_files, num_links;
14305 dir_links = 2 * ctx->fs_directory_count - 1;
14306 num_files = ctx->fs_total_count - dir_links;
14307 num_links = ctx->fs_links_count - dir_links;
14308 inodes = fs->super->s_inodes_count;
14309 inodes_used = (fs->super->s_inodes_count -
14310 fs->super->s_free_inodes_count);
14311 blocks = fs->super->s_blocks_count;
14312 blocks_used = (fs->super->s_blocks_count -
14313 fs->super->s_free_blocks_count);
14315 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
14316 frag_percent = (frag_percent + 5) / 10;
14319 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
14320 ctx->device_name, inodes_used, inodes,
14321 frag_percent / 10, frag_percent % 10,
14322 blocks_used, blocks);
14325 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
14326 100 * inodes_used / inodes);
14327 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
14328 P_E2("", "s", ctx->fs_fragmented),
14329 frag_percent / 10, frag_percent % 10);
14330 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
14331 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
14332 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
14333 (int) ((long long) 100 * blocks_used / blocks));
14334 printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
14335 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
14336 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
14337 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
14338 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
14339 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
14340 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
14341 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
14342 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
14343 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
14344 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
14345 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
14348 static void check_mount(e2fsck_t ctx)
14353 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
14354 &ctx->mount_flags);
14356 com_err("ext2fs_check_if_mount", retval,
14357 _("while determining whether %s is mounted."),
14358 ctx->filesystem_name);
14363 * If the filesystem isn't mounted, or it's the root filesystem
14364 * and it's mounted read-only, then everything's fine.
14366 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
14367 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
14368 (ctx->mount_flags & EXT2_MF_READONLY)))
14371 if (ctx->options & E2F_OPT_READONLY) {
14372 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
14376 printf(_("%s is mounted. "), ctx->filesystem_name);
14377 if (!ctx->interactive)
14378 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
14379 printf(_("\n\n\007\007\007\007WARNING!!! "
14380 "Running e2fsck on a mounted filesystem may cause\n"
14381 "SEVERE filesystem damage.\007\007\007\n\n"));
14382 cont = ask_yn(_("Do you really want to continue"), -1);
14384 printf (_("check aborted.\n"));
14390 static int is_on_batt(void)
14394 char tmp[80], tmp2[80], fname[80];
14395 unsigned int acflag;
14398 f = fopen("/proc/apm", "r");
14400 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
14403 return (acflag != 1);
14405 d = opendir("/proc/acpi/ac_adapter");
14407 while ((de=readdir(d)) != NULL) {
14408 if (!strncmp(".", de->d_name, 1))
14410 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
14412 f = fopen(fname, "r");
14415 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
14418 if (strncmp(tmp, "off-line", 8) == 0) {
14429 * This routine checks to see if a filesystem can be skipped; if so,
14430 * it will exit with EXIT_OK. Under some conditions it will print a
14431 * message explaining why a check is being forced.
14433 static void check_if_skip(e2fsck_t ctx)
14435 ext2_filsys fs = ctx->fs;
14436 const char *reason = NULL;
14437 unsigned int reason_arg = 0;
14439 int batt = is_on_batt();
14440 time_t now = time(0);
14442 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
14446 if ((fs->super->s_state & EXT2_ERROR_FS) ||
14447 !ext2fs_test_valid(fs))
14448 reason = _(" contains a file system with errors");
14449 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
14450 reason = _(" was not cleanly unmounted");
14451 else if ((fs->super->s_max_mnt_count > 0) &&
14452 (fs->super->s_mnt_count >=
14453 (unsigned) fs->super->s_max_mnt_count)) {
14454 reason = _(" has been mounted %u times without being checked");
14455 reason_arg = fs->super->s_mnt_count;
14456 if (batt && (fs->super->s_mnt_count <
14457 (unsigned) fs->super->s_max_mnt_count*2))
14459 } else if (fs->super->s_checkinterval &&
14460 ((now - fs->super->s_lastcheck) >=
14461 fs->super->s_checkinterval)) {
14462 reason = _(" has gone %u days without being checked");
14463 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
14464 if (batt && ((now - fs->super->s_lastcheck) <
14465 fs->super->s_checkinterval*2))
14469 fputs(ctx->device_name, stdout);
14470 printf(reason, reason_arg);
14471 fputs(_(", check forced.\n"), stdout);
14474 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
14475 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
14476 fs->super->s_inodes_count,
14477 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
14478 fs->super->s_blocks_count);
14479 next_check = 100000;
14480 if (fs->super->s_max_mnt_count > 0) {
14481 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
14482 if (next_check <= 0)
14485 if (fs->super->s_checkinterval &&
14486 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
14488 if (next_check <= 5) {
14489 if (next_check == 1)
14490 fputs(_(" (check after next mount)"), stdout);
14492 printf(_(" (check in %ld mounts)"), next_check);
14494 fputc('\n', stdout);
14497 e2fsck_free_context(ctx);
14502 * For completion notice
14504 struct percent_tbl {
14508 static const struct percent_tbl e2fsck_tbl = {
14509 5, { 0, 70, 90, 92, 95, 100 }
14512 static char bar[128], spaces[128];
14514 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
14521 if (pass > tbl->max_pass || max == 0)
14523 percent = ((float) curr) / ((float) max);
14524 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
14525 + tbl->table[pass-1]);
14528 void e2fsck_clear_progbar(e2fsck_t ctx)
14530 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
14533 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
14536 ctx->flags &= ~E2F_FLAG_PROG_BAR;
14539 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
14540 unsigned int dpynum)
14542 static const char spinner[] = "\\|/-";
14549 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
14553 * Calculate the new progress position. If the
14554 * percentage hasn't changed, then we skip out right
14557 fixed_percent = (int) ((10 * percent) + 0.5);
14558 if (ctx->progress_last_percent == fixed_percent)
14560 ctx->progress_last_percent = fixed_percent;
14563 * If we've already updated the spinner once within
14564 * the last 1/8th of a second, no point doing it
14567 gettimeofday(&tv, NULL);
14568 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
14569 if ((tick == ctx->progress_last_time) &&
14570 (fixed_percent != 0) && (fixed_percent != 1000))
14572 ctx->progress_last_time = tick;
14575 * Advance the spinner, and note that the progress bar
14576 * will be on the screen
14578 ctx->progress_pos = (ctx->progress_pos+1) & 3;
14579 ctx->flags |= E2F_FLAG_PROG_BAR;
14581 dpywidth = 66 - strlen(label);
14582 dpywidth = 8 * (dpywidth / 8);
14586 i = ((percent * dpywidth) + 50) / 100;
14587 printf("%s%s: |%s%s", ctx->start_meta, label,
14588 bar + (sizeof(bar) - (i+1)),
14589 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
14590 if (fixed_percent == 1000)
14591 fputc('|', stdout);
14593 fputc(spinner[ctx->progress_pos & 3], stdout);
14594 printf(" %4.1f%% ", percent);
14596 printf("%u\r", dpynum);
14598 fputs(" \r", stdout);
14599 fputs(ctx->stop_meta, stdout);
14601 if (fixed_percent == 1000)
14602 e2fsck_clear_progbar(ctx);
14608 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
14609 unsigned long cur, unsigned long max)
14617 if (ctx->progress_fd) {
14618 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
14619 write(ctx->progress_fd, buf, strlen(buf));
14621 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
14622 e2fsck_simple_progress(ctx, ctx->device_name,
14628 static void reserve_stdio_fds(void)
14633 fd = open(bb_dev_null, O_RDWR);
14637 fprintf(stderr, _("ERROR: Couldn't open "
14638 "/dev/null (%s)\n"),
14646 static void signal_progress_on(int sig FSCK_ATTR((unused)))
14648 e2fsck_t ctx = e2fsck_global_ctx;
14653 ctx->progress = e2fsck_update_progress;
14654 ctx->progress_fd = 0;
14657 static void signal_progress_off(int sig FSCK_ATTR((unused)))
14659 e2fsck_t ctx = e2fsck_global_ctx;
14664 e2fsck_clear_progbar(ctx);
14668 static void signal_cancel(int sig FSCK_ATTR((unused)))
14670 e2fsck_t ctx = e2fsck_global_ctx;
14673 exit(FSCK_CANCELED);
14675 ctx->flags |= E2F_FLAG_CANCEL;
14678 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
14680 char *buf, *token, *next, *p, *arg;
14682 int extended_usage = 0;
14684 buf = string_copy(opts, 0);
14685 for (token = buf; token && *token; token = next) {
14686 p = strchr(token, ',');
14692 arg = strchr(token, '=');
14697 if (strcmp(token, "ea_ver") == 0) {
14702 ea_ver = strtoul(arg, &p, 0);
14704 ((ea_ver != 1) && (ea_ver != 2))) {
14706 _("Invalid EA version.\n"));
14710 ctx->ext_attr_ver = ea_ver;
14712 fprintf(stderr, _("Unknown extended option: %s\n"),
14717 if (extended_usage) {
14718 bb_error_msg_and_die(
14719 "Extended options are separated by commas, "
14720 "and may take an argument which\n"
14721 "is set off by an equals ('=') sign. "
14722 "Valid extended options are:\n"
14723 "\tea_ver=<ea_version (1 or 2)>\n\n");
14728 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
14733 extern void *mallwatch;
14737 struct sigaction sa;
14738 char *extended_opts = 0;
14740 retval = e2fsck_allocate_context(&ctx);
14746 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
14747 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
14748 if (isatty(0) && isatty(1)) {
14749 ctx->interactive = 1;
14751 ctx->start_meta[0] = '\001';
14752 ctx->stop_meta[0] = '\002';
14754 memset(bar, '=', sizeof(bar)-1);
14755 memset(spaces, ' ', sizeof(spaces)-1);
14756 blkid_get_cache(&ctx->blkid, NULL);
14759 ctx->program_name = *argv;
14761 ctx->program_name = "e2fsck";
14762 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
14765 ctx->progress = e2fsck_update_progress;
14766 ctx->progress_fd = atoi(optarg);
14767 if (!ctx->progress_fd)
14769 /* Validate the file descriptor to avoid disasters */
14770 fd = dup(ctx->progress_fd);
14773 _("Error validating file descriptor %d: %s\n"),
14775 error_message(errno));
14777 _("Invalid completion information file descriptor"));
14782 ctx->options |= E2F_OPT_COMPRESS_DIRS;
14785 extended_opts = optarg;
14789 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
14792 _("Only one the options -p/-a, -n or -y may be specified."));
14794 ctx->options |= E2F_OPT_PREEN;
14797 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
14799 ctx->options |= E2F_OPT_NO;
14802 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
14804 ctx->options |= E2F_OPT_YES;
14807 #ifdef RESOURCE_TRACK
14808 if (ctx->options & E2F_OPT_TIME)
14809 ctx->options |= E2F_OPT_TIME2;
14811 ctx->options |= E2F_OPT_TIME;
14813 fprintf(stderr, _("The -t option is not "
14814 "supported on this version of e2fsck.\n"));
14819 ctx->options |= E2F_OPT_WRITECHECK;
14820 ctx->options |= E2F_OPT_CHECKBLOCKS;
14823 /* What we do by default, anyway! */
14826 ctx->use_superblock = atoi(optarg);
14827 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
14830 ctx->blocksize = atoi(optarg);
14833 ctx->inode_buffer_blocks = atoi(optarg);
14836 ctx->journal_name = string_copy(optarg, 0);
14839 ctx->process_inode_size = atoi(optarg);
14842 replace_bad_blocks++;
14844 bad_blocks_file = string_copy(optarg, 0);
14847 ctx->options |= E2F_OPT_DEBUG;
14850 ctx->options |= E2F_OPT_FORCE;
14859 show_version_only = 1;
14863 mallwatch = (void *) strtol(optarg, NULL, 0);
14867 ctx->device_name = optarg;
14869 #ifdef ENABLE_SWAPFS
14871 normalize_swapfs = 1;
14878 fprintf(stderr, _("Byte-swapping filesystems "
14879 "not compiled in this version "
14889 if (show_version_only)
14891 if (optind != argc - 1)
14893 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
14894 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
14895 ctx->options |= E2F_OPT_READONLY;
14896 ctx->io_options = strchr(argv[optind], '?');
14897 if (ctx->io_options)
14898 *ctx->io_options++ = 0;
14899 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
14900 if (!ctx->filesystem_name) {
14901 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
14903 fatal_error(ctx, 0);
14906 parse_extended_opts(ctx, extended_opts);
14909 fd = open(ctx->filesystem_name, O_RDONLY, 0);
14911 com_err("open", errno,
14912 _("while opening %s for flushing"),
14913 ctx->filesystem_name);
14914 fatal_error(ctx, 0);
14916 if ((retval = ext2fs_sync_device(fd, 1))) {
14917 com_err("ext2fs_sync_device", retval,
14918 _("while trying to flush %s"),
14919 ctx->filesystem_name);
14920 fatal_error(ctx, 0);
14924 #ifdef ENABLE_SWAPFS
14926 if (cflag || bad_blocks_file) {
14927 fprintf(stderr, _("Incompatible options not "
14928 "allowed when byte-swapping.\n"));
14933 if (cflag && bad_blocks_file) {
14934 fprintf(stderr, _("The -c and the -l/-L options may "
14935 "not be both used at the same time.\n"));
14939 * Set up signal action
14941 memset(&sa, 0, sizeof(struct sigaction));
14942 sa.sa_handler = signal_cancel;
14943 sigaction(SIGINT, &sa, 0);
14944 sigaction(SIGTERM, &sa, 0);
14946 sa.sa_flags = SA_RESTART;
14948 e2fsck_global_ctx = ctx;
14949 sa.sa_handler = signal_progress_on;
14950 sigaction(SIGUSR1, &sa, 0);
14951 sa.sa_handler = signal_progress_off;
14952 sigaction(SIGUSR2, &sa, 0);
14954 /* Update our PATH to include /sbin if we need to run badblocks */
14956 e2fs_set_sbin_path();
14957 #ifdef __CONFIG_JBD_DEBUG__E2FS
14958 if (getenv("E2FSCK_JBD_DEBUG"))
14959 journal_enable_debug = atoi(getenv("E2FSCK_JBD_DEBUG"));
14964 static const char my_ver_string[] = E2FSPROGS_VERSION;
14965 static const char my_ver_date[] = E2FSPROGS_DATE;
14967 int e2fsck_main (int argc, char *argv[])
14970 int exit_value = EXIT_OK;
14971 ext2_filsys fs = 0;
14973 struct ext2_super_block *sb;
14974 const char *lib_ver_date;
14975 int my_ver, lib_ver;
14977 struct problem_context pctx;
14978 int flags, run_result;
14980 clear_problem_context(&pctx);
14988 setlocale(LC_MESSAGES, "");
14989 setlocale(LC_CTYPE, "");
14990 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
14991 textdomain(NLS_CAT_NAME);
14993 my_ver = ext2fs_parse_version_string(my_ver_string);
14994 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
14995 if (my_ver > lib_ver) {
14996 fprintf( stderr, _("Error: ext2fs library version "
14997 "out of date!\n"));
14998 show_version_only++;
15001 retval = PRS(argc, argv, &ctx);
15003 com_err("e2fsck", retval,
15004 _("while trying to initialize program"));
15007 reserve_stdio_fds();
15009 #ifdef RESOURCE_TRACK
15010 init_resource_track(&ctx->global_rtrack);
15013 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
15014 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
15017 if (show_version_only) {
15018 fprintf(stderr, _("\tUsing %s, %s\n"),
15019 error_message(EXT2_ET_BASE), lib_ver_date);
15025 if (!(ctx->options & E2F_OPT_PREEN) &&
15026 !(ctx->options & E2F_OPT_NO) &&
15027 !(ctx->options & E2F_OPT_YES)) {
15028 if (!ctx->interactive)
15030 _("need terminal for interactive repairs"));
15032 ctx->superblock = ctx->use_superblock;
15034 #ifdef CONFIG_TESTIO_DEBUG
15035 io_ptr = test_io_manager;
15036 test_io_backing_manager = unix_io_manager;
15038 io_ptr = unix_io_manager;
15041 if ((ctx->options & E2F_OPT_READONLY) == 0)
15042 flags |= EXT2_FLAG_RW;
15044 if (ctx->superblock && ctx->blocksize) {
15045 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
15046 flags, ctx->superblock, ctx->blocksize,
15048 } else if (ctx->superblock) {
15050 for (blocksize = EXT2_MIN_BLOCK_SIZE;
15051 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
15052 retval = ext2fs_open2(ctx->filesystem_name,
15053 ctx->io_options, flags,
15054 ctx->superblock, blocksize,
15060 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
15061 flags, 0, 0, io_ptr, &fs);
15062 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
15063 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
15064 ((retval == EXT2_ET_BAD_MAGIC) ||
15065 ((retval == 0) && ext2fs_check_desc(fs)))) {
15066 if (!fs || (fs->group_desc_count > 1)) {
15067 printf(_("%s trying backup blocks...\n"),
15068 retval ? _("Couldn't find ext2 superblock,") :
15069 _("Group descriptors look bad..."));
15070 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
15077 com_err(ctx->program_name, retval, _("while trying to open %s"),
15078 ctx->filesystem_name);
15079 if (retval == EXT2_ET_REV_TOO_HIGH) {
15080 printf(_("The filesystem revision is apparently "
15081 "too high for this version of e2fsck.\n"
15082 "(Or the filesystem superblock "
15083 "is corrupt)\n\n"));
15084 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
15085 } else if (retval == EXT2_ET_SHORT_READ)
15086 printf(_("Could this be a zero-length partition?\n"));
15087 else if ((retval == EPERM) || (retval == EACCES))
15088 printf(_("You must have %s access to the "
15089 "filesystem or be root\n"),
15090 (ctx->options & E2F_OPT_READONLY) ?
15092 else if (retval == ENXIO)
15093 printf(_("Possibly non-existent or swap device?\n"));
15095 else if (retval == EROFS)
15096 printf(_("Disk write-protected; use the -n option "
15097 "to do a read-only\n"
15098 "check of the device.\n"));
15101 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
15102 fatal_error(ctx, 0);
15105 fs->priv_data = ctx;
15107 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
15108 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
15109 _("while trying to open %s"),
15110 ctx->filesystem_name);
15112 fatal_error(ctx, _("Get a newer version of e2fsck!"));
15116 * Set the device name, which is used whenever we print error
15117 * or informational messages to the user.
15119 if (ctx->device_name == 0 &&
15120 (sb->s_volume_name[0] != 0)) {
15121 ctx->device_name = string_copy(sb->s_volume_name,
15122 sizeof(sb->s_volume_name));
15124 if (ctx->device_name == 0)
15125 ctx->device_name = ctx->filesystem_name;
15128 * Make sure the ext3 superblock fields are consistent.
15130 retval = e2fsck_check_ext3_journal(ctx);
15132 com_err(ctx->program_name, retval,
15133 _("while checking ext3 journal for %s"),
15135 fatal_error(ctx, 0);
15139 * Check to see if we need to do ext3-style recovery. If so,
15140 * do it, and then restart the fsck.
15142 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
15143 if (ctx->options & E2F_OPT_READONLY) {
15144 printf(_("Warning: skipping journal recovery "
15145 "because doing a read-only filesystem "
15147 io_channel_flush(ctx->fs->io);
15149 if (ctx->flags & E2F_FLAG_RESTARTED) {
15151 * Whoops, we attempted to run the
15152 * journal twice. This should never
15153 * happen, unless the hardware or
15154 * device driver is being bogus.
15156 com_err(ctx->program_name, 0,
15157 _("unable to set superblock flags on %s\n"), ctx->device_name);
15158 fatal_error(ctx, 0);
15160 retval = e2fsck_run_ext3_journal(ctx);
15162 com_err(ctx->program_name, retval,
15163 _("while recovering ext3 journal of %s"),
15165 fatal_error(ctx, 0);
15167 ext2fs_close(ctx->fs);
15169 ctx->flags |= E2F_FLAG_RESTARTED;
15175 * Check for compatibility with the feature sets. We need to
15176 * be more stringent than ext2fs_open().
15178 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
15179 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
15180 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
15181 "(%s)", ctx->device_name);
15184 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
15185 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
15186 "(%s)", ctx->device_name);
15189 #ifdef ENABLE_COMPRESSION
15190 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
15191 com_err(ctx->program_name, 0,
15192 _("Warning: compression support is experimental.\n"));
15194 #ifndef ENABLE_HTREE
15195 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
15196 com_err(ctx->program_name, 0,
15197 _("E2fsck not compiled with HTREE support,\n\t"
15198 "but filesystem %s has HTREE directories.\n"),
15205 * If the user specified a specific superblock, presumably the
15206 * master superblock has been trashed. So we mark the
15207 * superblock as dirty, so it can be written out.
15209 if (ctx->superblock &&
15210 !(ctx->options & E2F_OPT_READONLY))
15211 ext2fs_mark_super_dirty(fs);
15214 * We only update the master superblock because (a) paranoia;
15215 * we don't want to corrupt the backup superblocks, and (b) we
15216 * don't need to update the mount count and last checked
15217 * fields in the backup superblock (the kernel doesn't
15218 * update the backup superblocks anyway).
15220 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
15222 ehandler_init(fs->io);
15224 if (ctx->superblock)
15225 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
15226 ext2fs_mark_valid(fs);
15227 check_super_block(ctx);
15228 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15229 fatal_error(ctx, 0);
15230 check_if_skip(ctx);
15231 if (bad_blocks_file)
15232 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
15234 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
15235 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15236 fatal_error(ctx, 0);
15237 #ifdef ENABLE_SWAPFS
15239 #ifdef WORDS_BIGENDIAN
15240 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
15242 #define NATIVE_FLAG 0
15246 if (normalize_swapfs) {
15247 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
15248 fprintf(stderr, _("%s: Filesystem byte order "
15249 "already normalized.\n"), ctx->device_name);
15250 fatal_error(ctx, 0);
15255 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15256 fatal_error(ctx, 0);
15261 * Mark the system as valid, 'til proven otherwise
15263 ext2fs_mark_valid(fs);
15265 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
15267 com_err(ctx->program_name, retval,
15268 _("while reading bad blocks inode"));
15270 printf(_("This doesn't bode well,"
15271 " but we'll try to go on...\n"));
15274 run_result = e2fsck_run(ctx);
15275 e2fsck_clear_progbar(ctx);
15276 if (run_result == E2F_FLAG_RESTART) {
15277 printf(_("Restarting e2fsck from the beginning...\n"));
15278 retval = e2fsck_reset_context(ctx);
15280 com_err(ctx->program_name, retval,
15281 _("while resetting context"));
15282 fatal_error(ctx, 0);
15287 if (run_result & E2F_FLAG_CANCEL) {
15288 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
15289 ctx->device_name : ctx->filesystem_name);
15290 exit_value |= FSCK_CANCELED;
15292 if (run_result & E2F_FLAG_ABORT)
15293 fatal_error(ctx, _("aborted"));
15296 mtrace_print("Cleanup");
15298 if (ext2fs_test_changed(fs)) {
15299 exit_value |= EXIT_NONDESTRUCT;
15300 if (!(ctx->options & E2F_OPT_PREEN))
15301 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
15303 if (ctx->mount_flags & EXT2_MF_ISROOT) {
15304 printf(_("%s: ***** REBOOT LINUX *****\n"),
15306 exit_value |= EXIT_DESTRUCT;
15309 if (!ext2fs_test_valid(fs)) {
15310 printf(_("\n%s: ********** WARNING: Filesystem still has "
15311 "errors **********\n\n"), ctx->device_name);
15312 exit_value |= EXIT_UNCORRECTED;
15313 exit_value &= ~EXIT_NONDESTRUCT;
15315 if (exit_value & FSCK_CANCELED)
15316 exit_value &= ~EXIT_NONDESTRUCT;
15319 if (!(ctx->options & E2F_OPT_READONLY)) {
15320 if (ext2fs_test_valid(fs)) {
15321 if (!(sb->s_state & EXT2_VALID_FS))
15322 exit_value |= EXIT_NONDESTRUCT;
15323 sb->s_state = EXT2_VALID_FS;
15325 sb->s_state &= ~EXT2_VALID_FS;
15326 sb->s_mnt_count = 0;
15327 sb->s_lastcheck = time(NULL);
15328 ext2fs_mark_super_dirty(fs);
15332 e2fsck_write_bitmaps(ctx);
15336 free(ctx->filesystem_name);
15337 free(ctx->journal_name);
15338 e2fsck_free_context(ctx);
15340 #ifdef RESOURCE_TRACK
15341 if (ctx->options & E2F_OPT_TIME)
15342 print_resource_track(NULL, &ctx->global_rtrack);