2 * pass2.c --- check directory structure
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o
7 * This file may be redistributed under the terms of the GNU Public
11 * Pass 2 of e2fsck iterates through all active directory inodes, and
12 * applies to following tests to each directory entry in the directory
13 * blocks in the inodes:
15 * - The length of the directory entry (rec_len) should be at
16 * least 8 bytes, and no more than the remaining space
17 * left in the directory block.
18 * - The length of the name in the directory entry (name_len)
19 * should be less than (rec_len - 8).
20 * - The inode number in the directory entry should be within
22 * - The inode number should refer to a in-use inode.
23 * - The first entry should be '.', and its inode should be
24 * the inode of the directory.
25 * - The second entry should be '..'.
27 * To minimize disk seek time, the directory blocks are processed in
28 * sorted order of block numbers.
30 * Pass 2 also collects the following information:
31 * - The inode numbers of the subdirectories for each directory.
33 * Pass 2 relies on the following information from previous passes:
34 * - The directory information collected in pass 1.
35 * - The inode_used_map bitmap
36 * - The inode_bad_map bitmap
37 * - The inode_dir_map bitmap
39 * Pass 2 frees the following data structures
40 * - The inode_bad_map bitmap
41 * - The inode_reg_map bitmap
47 #ifdef NO_INLINE_FUNCS
50 #define _INLINE_ inline
56 * Keeps track of how many times an inode is referenced.
58 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
);
59 static int check_dir_block(ext2_filsys fs
,
60 struct ext2_db_entry
*dir_blocks_info
,
62 static int allocate_dir_block(e2fsck_t ctx
,
63 struct ext2_db_entry
*dir_blocks_info
,
64 char *buf
, struct problem_context
*pctx
);
65 static int update_dir_block(ext2_filsys fs
,
71 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
);
72 static EXT2_QSORT_TYPE
special_dir_block_cmp(const void *a
, const void *b
);
74 struct check_dir_struct
{
76 struct problem_context pctx
;
81 void e2fsck_pass2(e2fsck_t ctx
)
83 struct ext2_super_block
*sb
= ctx
->fs
->super
;
84 struct problem_context pctx
;
85 ext2_filsys fs
= ctx
->fs
;
88 struct resource_track rtrack
;
91 struct check_dir_struct cd
;
92 struct dx_dir_info
*dx_dir
;
93 struct dx_dirblock_info
*dx_db
, *dx_parent
;
100 init_resource_track(&rtrack
);
103 clear_problem_context(&cd
.pctx
);
106 mtrace_print("Pass 2");
109 if (!(ctx
->options
& E2F_OPT_PREEN
))
110 fix_problem(ctx
, PR_2_PASS_HEADER
, &cd
.pctx
);
112 cd
.pctx
.errcode
= ext2fs_create_icount2(fs
, EXT2_ICOUNT_OPT_INCREMENT
,
113 0, ctx
->inode_link_info
,
115 if (cd
.pctx
.errcode
) {
116 fix_problem(ctx
, PR_2_ALLOCATE_ICOUNT
, &cd
.pctx
);
117 ctx
->flags
|= E2F_FLAG_ABORT
;
120 buf
= (char *) e2fsck_allocate_memory(ctx
, 2*fs
->blocksize
,
121 "directory scan buffer");
124 * Set up the parent pointer for the root directory, if
125 * present. (If the root directory is not present, we will
126 * create it in pass 3.)
128 dir
= e2fsck_get_dir_info(ctx
, EXT2_ROOT_INO
);
130 dir
->parent
= EXT2_ROOT_INO
;
135 cd
.max
= ext2fs_dblist_count(fs
->dblist
);
138 (void) (ctx
->progress
)(ctx
, 2, 0, cd
.max
);
140 if (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
)
141 ext2fs_dblist_sort(fs
->dblist
, special_dir_block_cmp
);
143 cd
.pctx
.errcode
= ext2fs_dblist_iterate(fs
->dblist
, check_dir_block
,
145 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
147 if (cd
.pctx
.errcode
) {
148 fix_problem(ctx
, PR_2_DBLIST_ITERATE
, &cd
.pctx
);
149 ctx
->flags
|= E2F_FLAG_ABORT
;
154 for (i
=0; (dx_dir
= e2fsck_dx_dir_info_iter(ctx
, &i
)) != 0;) {
155 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
157 if (dx_dir
->numblocks
== 0)
159 clear_problem_context(&pctx
);
161 pctx
.dir
= dx_dir
->ino
;
162 dx_db
= dx_dir
->dx_block
;
163 if (dx_db
->flags
& DX_FLAG_REFERENCED
)
164 dx_db
->flags
|= DX_FLAG_DUP_REF
;
166 dx_db
->flags
|= DX_FLAG_REFERENCED
;
168 * Find all of the first and last leaf blocks, and
169 * update their parent's min and max hash values
171 for (b
=0, dx_db
= dx_dir
->dx_block
;
172 b
< dx_dir
->numblocks
;
174 if ((dx_db
->type
!= DX_DIRBLOCK_LEAF
) ||
175 !(dx_db
->flags
& (DX_FLAG_FIRST
| DX_FLAG_LAST
)))
177 dx_parent
= &dx_dir
->dx_block
[dx_db
->parent
];
179 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
181 if (dx_db
->flags
& DX_FLAG_FIRST
)
182 dx_parent
->min_hash
= dx_db
->min_hash
;
184 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
186 if (dx_db
->flags
& DX_FLAG_LAST
)
187 dx_parent
->max_hash
= dx_db
->max_hash
;
190 for (b
=0, dx_db
= dx_dir
->dx_block
;
191 b
< dx_dir
->numblocks
;
194 pctx
.group
= dx_db
->parent
;
196 if (!(dx_db
->flags
& DX_FLAG_FIRST
) &&
197 (dx_db
->min_hash
< dx_db
->node_min_hash
)) {
198 pctx
.blk
= dx_db
->min_hash
;
199 pctx
.blk2
= dx_db
->node_min_hash
;
200 code
= PR_2_HTREE_MIN_HASH
;
201 fix_problem(ctx
, code
, &pctx
);
205 * This test doesn't apply for the root block
209 (dx_db
->max_hash
> dx_db
->node_max_hash
)) {
210 pctx
.blk
= dx_db
->max_hash
;
211 pctx
.blk2
= dx_db
->node_max_hash
;
212 code
= PR_2_HTREE_MAX_HASH
;
213 fix_problem(ctx
, code
, &pctx
);
216 if (!(dx_db
->flags
& DX_FLAG_REFERENCED
)) {
217 code
= PR_2_HTREE_NOTREF
;
218 fix_problem(ctx
, code
, &pctx
);
220 } else if (dx_db
->flags
& DX_FLAG_DUP_REF
) {
221 code
= PR_2_HTREE_DUPREF
;
222 fix_problem(ctx
, code
, &pctx
);
228 if (bad_dir
&& fix_problem(ctx
, PR_2_HTREE_CLEAR
, &pctx
)) {
229 clear_htree(ctx
, dx_dir
->ino
);
230 dx_dir
->numblocks
= 0;
232 #ifdef ENABLE_HTREE_CLEAR
233 if (dx_dir
->numblocks
) {
234 fix_problem(ctx
, PR_2_HTREE_FCLR
, &pctx
);
235 clear_htree(ctx
, dx_dir
->ino
);
236 dx_dir
->numblocks
= 0;
241 ext2fs_free_mem((void **) &buf
);
242 ext2fs_free_dblist(fs
->dblist
);
244 if (ctx
->inode_bad_map
) {
245 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
246 ctx
->inode_bad_map
= 0;
248 if (ctx
->inode_reg_map
) {
249 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
250 ctx
->inode_reg_map
= 0;
253 clear_problem_context(&pctx
);
254 if (ctx
->large_files
) {
255 if (!(sb
->s_feature_ro_compat
&
256 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
) &&
257 fix_problem(ctx
, PR_2_FEATURE_LARGE_FILES
, &pctx
)) {
258 sb
->s_feature_ro_compat
|=
259 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
260 ext2fs_mark_super_dirty(fs
);
262 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
263 fix_problem(ctx
, PR_1_FS_REV_LEVEL
, &pctx
)) {
264 ext2fs_update_dynamic_rev(fs
);
265 ext2fs_mark_super_dirty(fs
);
267 } else if (!ctx
->large_files
&&
268 (sb
->s_feature_ro_compat
&
269 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
)) {
270 if (fs
->flags
& EXT2_FLAG_RW
) {
271 sb
->s_feature_ro_compat
&=
272 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
273 ext2fs_mark_super_dirty(fs
);
277 #ifdef RESOURCE_TRACK
278 if (ctx
->options
& E2F_OPT_TIME2
) {
279 e2fsck_clear_progbar(ctx
);
280 print_resource_track("Pass 2", &rtrack
);
286 * This is special sort function that makes sure that directory blocks
287 * with a dirblock of zero are sorted to the beginning of the list.
288 * This guarantees that the root node of the htree directories are
289 * processed first, so we know what hash version to use.
291 static EXT2_QSORT_TYPE
special_dir_block_cmp(const void *a
, const void *b
)
293 const struct ext2_db_entry
*db_a
=
294 (const struct ext2_db_entry
*) a
;
295 const struct ext2_db_entry
*db_b
=
296 (const struct ext2_db_entry
*) b
;
298 if (db_a
->blockcnt
&& !db_b
->blockcnt
)
301 if (!db_a
->blockcnt
&& db_b
->blockcnt
)
304 if (db_a
->blk
!= db_b
->blk
)
305 return (int) (db_a
->blk
- db_b
->blk
);
307 if (db_a
->ino
!= db_b
->ino
)
308 return (int) (db_a
->ino
- db_b
->ino
);
310 return (int) (db_a
->blockcnt
- db_b
->blockcnt
);
315 * Make sure the first entry in the directory is '.', and that the
316 * directory entry is sane.
318 static int check_dot(e2fsck_t ctx
,
319 struct ext2_dir_entry
*dirent
,
320 ext2_ino_t ino
, struct problem_context
*pctx
)
322 struct ext2_dir_entry
*nextdir
;
329 problem
= PR_2_MISSING_DOT
;
330 else if (((dirent
->name_len
& 0xFF) != 1) ||
331 (dirent
->name
[0] != '.'))
332 problem
= PR_2_1ST_NOT_DOT
;
333 else if (dirent
->name
[1] != '\0')
334 problem
= PR_2_DOT_NULL_TERM
;
337 if (fix_problem(ctx
, problem
, pctx
)) {
338 if (dirent
->rec_len
< 12)
339 dirent
->rec_len
= 12;
341 dirent
->name_len
= 1;
342 dirent
->name
[0] = '.';
343 dirent
->name
[1] = '\0';
348 if (dirent
->inode
!= ino
) {
349 if (fix_problem(ctx
, PR_2_BAD_INODE_DOT
, pctx
)) {
354 if (dirent
->rec_len
> 12) {
355 new_len
= dirent
->rec_len
- 12;
358 fix_problem(ctx
, PR_2_SPLIT_DOT
, pctx
)) {
359 nextdir
= (struct ext2_dir_entry
*)
360 ((char *) dirent
+ 12);
361 dirent
->rec_len
= 12;
362 nextdir
->rec_len
= new_len
;
364 nextdir
->name_len
= 0;
373 * Make sure the second entry in the directory is '..', and that the
374 * directory entry is sane. We do not check the inode number of '..'
375 * here; this gets done in pass 3.
377 static int check_dotdot(e2fsck_t ctx
,
378 struct ext2_dir_entry
*dirent
,
379 struct dir_info
*dir
, struct problem_context
*pctx
)
384 problem
= PR_2_MISSING_DOT_DOT
;
385 else if (((dirent
->name_len
& 0xFF) != 2) ||
386 (dirent
->name
[0] != '.') ||
387 (dirent
->name
[1] != '.'))
388 problem
= PR_2_2ND_NOT_DOT_DOT
;
389 else if (dirent
->name
[2] != '\0')
390 problem
= PR_2_DOT_DOT_NULL_TERM
;
393 if (fix_problem(ctx
, problem
, pctx
)) {
394 if (dirent
->rec_len
< 12)
395 dirent
->rec_len
= 12;
397 * Note: we don't have the parent inode just
398 * yet, so we will fill it in with the root
399 * inode. This will get fixed in pass 3.
401 dirent
->inode
= EXT2_ROOT_INO
;
402 dirent
->name_len
= 2;
403 dirent
->name
[0] = '.';
404 dirent
->name
[1] = '.';
405 dirent
->name
[2] = '\0';
410 dir
->dotdot
= dirent
->inode
;
415 * Check to make sure a directory entry doesn't contain any illegal
418 static int check_name(e2fsck_t ctx
,
419 struct ext2_dir_entry
*dirent
,
420 ext2_ino_t dir_ino
, struct problem_context
*pctx
)
426 for ( i
= 0; i
< (dirent
->name_len
& 0xFF); i
++) {
427 if (dirent
->name
[i
] == '/' || dirent
->name
[i
] == '\0') {
429 fixup
= fix_problem(ctx
, PR_2_BAD_NAME
, pctx
);
432 dirent
->name
[i
] = '.';
441 * Check the directory filetype (if present)
443 static _INLINE_
int check_filetype(e2fsck_t ctx
,
444 struct ext2_dir_entry
*dirent
,
445 ext2_ino_t dir_ino
, struct problem_context
*pctx
)
447 int filetype
= dirent
->name_len
>> 8;
448 int should_be
= EXT2_FT_UNKNOWN
;
449 struct ext2_inode inode
;
451 if (!(ctx
->fs
->super
->s_feature_incompat
&
452 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
454 !fix_problem(ctx
, PR_2_CLEAR_FILETYPE
, pctx
))
456 dirent
->name_len
= dirent
->name_len
& 0xFF;
460 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, dirent
->inode
)) {
461 should_be
= EXT2_FT_DIR
;
462 } else if (ext2fs_test_inode_bitmap(ctx
->inode_reg_map
,
464 should_be
= EXT2_FT_REG_FILE
;
465 } else if (ctx
->inode_bad_map
&&
466 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
470 e2fsck_read_inode(ctx
, dirent
->inode
, &inode
,
472 should_be
= ext2_file_type(inode
.i_mode
);
474 if (filetype
== should_be
)
476 pctx
->num
= should_be
;
478 if (fix_problem(ctx
, filetype
? PR_2_BAD_FILETYPE
: PR_2_SET_FILETYPE
,
482 dirent
->name_len
= (dirent
->name_len
& 0xFF) | should_be
<< 8;
487 static void parse_int_node(ext2_filsys fs
,
488 struct ext2_db_entry
*db
,
489 struct check_dir_struct
*cd
,
490 struct dx_dir_info
*dx_dir
,
493 struct ext2_dx_root_info
*root
;
494 struct ext2_dx_entry
*ent
;
495 struct ext2_dx_countlimit
*limit
;
496 struct dx_dirblock_info
*dx_db
;
499 ext2_dirhash_t min_hash
= 0xffffffff;
500 ext2_dirhash_t max_hash
= 0;
501 ext2_dirhash_t hash
= 0;
503 if (db
->blockcnt
== 0) {
504 root
= (struct ext2_dx_root_info
*) (block_buf
+ 24);
507 printf("Root node dump:\n");
508 printf("\t Reserved zero: %d\n", root
->reserved_zero
);
509 printf("\t Hash Version: %d\n", root
->hash_version
);
510 printf("\t Info length: %d\n", root
->info_length
);
511 printf("\t Indirect levels: %d\n", root
->indirect_levels
);
512 printf("\t Flags: %d\n", root
->unused_flags
);
515 ent
= (struct ext2_dx_entry
*) (block_buf
+ 24 + root
->info_length
);
517 ent
= (struct ext2_dx_entry
*) (block_buf
+8);
519 limit
= (struct ext2_dx_countlimit
*) ent
;
522 printf("Number of entries (count): %d\n", limit
->count
);
523 printf("Number of entries (limit): %d\n", limit
->limit
);
526 for (i
=0; i
< limit
->count
; i
++) {
527 hash
= i
? (ent
[i
].hash
& ~1) : 0;
529 * XXX Check to make make sure the hash[i] < hash[i+1]
532 printf("Entry #%d: Hash 0x%08x, block %d\n", i
,
535 blk
= ent
[i
].block
& 0x0ffffff;
536 /* Check to make sure the block is valid */
537 if (blk
> dx_dir
->numblocks
) {
539 if (fix_problem(cd
->ctx
, PR_2_HTREE_BADBLK
,
541 clear_htree(cd
->ctx
, cd
->pctx
.ino
);
542 dx_dir
->numblocks
= 0;
546 dx_db
= &dx_dir
->dx_block
[blk
];
547 if (dx_db
->flags
& DX_FLAG_REFERENCED
) {
548 dx_db
->flags
|= DX_FLAG_DUP_REF
;
550 dx_db
->flags
|= DX_FLAG_REFERENCED
;
551 dx_db
->parent
= db
->blockcnt
;
557 dx_db
->node_min_hash
= hash
;
558 if ((i
+1) < limit
->count
)
559 dx_db
->node_max_hash
= (ent
[i
+1].hash
& ~1);
561 dx_db
->node_max_hash
= 0xfffffffe;
562 dx_db
->flags
|= DX_FLAG_LAST
;
565 dx_db
->flags
|= DX_FLAG_FIRST
;
568 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
569 db
->blockcnt
, min_hash
, max_hash
);
571 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
572 dx_db
->min_hash
= min_hash
;
573 dx_db
->max_hash
= max_hash
;
575 #endif /* ENABLE_HTREE */
578 * Given a busted directory, try to salvage it somehow.
581 static int salvage_directory(ext2_filsys fs
,
582 struct ext2_dir_entry
*dirent
,
583 struct ext2_dir_entry
*prev
,
586 char *cp
= (char *) dirent
;
587 int left
= fs
->blocksize
- offset
- dirent
->rec_len
;
588 int prev_offset
= offset
- ((char *) dirent
- (char *) prev
);
591 * Special case of directory entry of size 8: copy what's left
592 * of the directory block up to cover up the invalid hole.
594 if ((left
>= 12) && (dirent
->rec_len
== 8)) {
595 memmove(cp
, cp
+8, left
);
596 memset(cp
+ left
, 0, 8);
600 * If the directory entry is a multiple of four, so it is
601 * valid, let the previous directory entry absorb the invalid
604 if (prev
&& dirent
->rec_len
&& (dirent
->rec_len
% 4) == 0) {
605 prev
->rec_len
+= dirent
->rec_len
;
609 * Default salvage method --- kill all of the directory
610 * entries for the rest of the block. We will either try to
611 * absorb it into the previous directory entry, or create a
612 * new empty directory entry the rest of the directory block.
615 prev
->rec_len
+= fs
->blocksize
- offset
;
618 dirent
->rec_len
= fs
->blocksize
- offset
;
619 dirent
->name_len
= 0;
626 static int check_dir_block(ext2_filsys fs
,
627 struct ext2_db_entry
*db
,
630 struct dir_info
*subdir
, *dir
;
631 struct dx_dir_info
*dx_dir
;
633 struct dx_dirblock_info
*dx_db
= 0;
634 #endif /* ENABLE_HTREE */
635 struct ext2_dir_entry
*dirent
, *prev
;
638 int dir_modified
= 0;
640 blk_t block_nr
= db
->blk
;
641 ext2_ino_t ino
= db
->ino
;
643 struct check_dir_struct
*cd
;
647 struct ext2_dx_root_info
*root
;
648 struct ext2_dx_countlimit
*limit
;
650 cd
= (struct check_dir_struct
*) priv_data
;
654 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
657 if (ctx
->progress
&& (ctx
->progress
)(ctx
, 2, cd
->count
++, cd
->max
))
661 * Make sure the inode is still in use (could have been
662 * deleted in the duplicate/bad blocks pass.
664 if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
, ino
)))
668 cd
->pctx
.blk
= block_nr
;
669 cd
->pctx
.blkcount
= db
->blockcnt
;
675 if (allocate_dir_block(ctx
, db
, buf
, &cd
->pctx
))
686 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr
,
690 cd
->pctx
.errcode
= ext2fs_read_dir_block(fs
, block_nr
, buf
);
691 if (cd
->pctx
.errcode
== EXT2_ET_DIR_CORRUPTED
)
692 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
693 if (cd
->pctx
.errcode
) {
694 if (!fix_problem(ctx
, PR_2_READ_DIRBLOCK
, &cd
->pctx
)) {
695 ctx
->flags
|= E2F_FLAG_ABORT
;
698 memset(buf
, 0, fs
->blocksize
);
701 dx_dir
= e2fsck_get_dx_dir_info(ctx
, ino
);
702 if (dx_dir
&& dx_dir
->numblocks
) {
703 if (db
->blockcnt
>= dx_dir
->numblocks
) {
704 printf("XXX should never happen!!!\n");
707 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
708 dx_db
->type
= DX_DIRBLOCK_LEAF
;
709 dx_db
->phys
= block_nr
;
710 dx_db
->min_hash
= ~0;
713 dirent
= (struct ext2_dir_entry
*) buf
;
714 limit
= (struct ext2_dx_countlimit
*) (buf
+8);
715 if (db
->blockcnt
== 0) {
716 root
= (struct ext2_dx_root_info
*) (buf
+ 24);
717 dx_db
->type
= DX_DIRBLOCK_ROOT
;
718 dx_db
->flags
|= DX_FLAG_FIRST
| DX_FLAG_LAST
;
719 if ((root
->reserved_zero
||
720 root
->info_length
< 8 ||
721 root
->indirect_levels
> 1) &&
722 fix_problem(ctx
, PR_2_HTREE_BAD_ROOT
, &cd
->pctx
)) {
723 clear_htree(ctx
, ino
);
724 dx_dir
->numblocks
= 0;
727 dx_dir
->hashversion
= root
->hash_version
;
728 } else if ((dirent
->inode
== 0) &&
729 (dirent
->rec_len
== fs
->blocksize
) &&
730 (dirent
->name_len
== 0) &&
731 (limit
->limit
== ((fs
->blocksize
-8) /
732 sizeof(struct ext2_dx_entry
))))
733 dx_db
->type
= DX_DIRBLOCK_NODE
;
735 #endif /* ENABLE_HTREE */
740 dirent
= (struct ext2_dir_entry
*) (buf
+ offset
);
741 cd
->pctx
.dirent
= dirent
;
742 cd
->pctx
.num
= offset
;
743 if (((offset
+ dirent
->rec_len
) > fs
->blocksize
) ||
744 (dirent
->rec_len
< 12) ||
745 ((dirent
->rec_len
% 4) != 0) ||
746 (((dirent
->name_len
& 0xFF)+8) > dirent
->rec_len
)) {
747 if (fix_problem(ctx
, PR_2_DIR_CORRUPTED
, &cd
->pctx
)) {
748 offset
= salvage_directory(fs
, dirent
,
755 if ((dirent
->name_len
& 0xFF) > EXT2_NAME_LEN
) {
756 if (fix_problem(ctx
, PR_2_FILENAME_LONG
, &cd
->pctx
)) {
757 dirent
->name_len
= EXT2_NAME_LEN
;
762 if (dot_state
== 0) {
763 if (check_dot(ctx
, dirent
, ino
, &cd
->pctx
))
765 } else if (dot_state
== 1) {
766 dir
= e2fsck_get_dir_info(ctx
, ino
);
768 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
769 ctx
->flags
|= E2F_FLAG_ABORT
;
772 if (check_dotdot(ctx
, dirent
, dir
, &cd
->pctx
))
774 } else if (dirent
->inode
== ino
) {
775 problem
= PR_2_LINK_DOT
;
776 if (fix_problem(ctx
, PR_2_LINK_DOT
, &cd
->pctx
)) {
786 * Make sure the inode listed is a legal one.
788 if (((dirent
->inode
!= EXT2_ROOT_INO
) &&
789 (dirent
->inode
< EXT2_FIRST_INODE(fs
->super
))) ||
790 (dirent
->inode
> fs
->super
->s_inodes_count
)) {
791 problem
= PR_2_BAD_INO
;
792 } else if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
,
795 * If the inode is unused, offer to clear it.
797 problem
= PR_2_UNUSED_INODE
;
798 } else if (ctx
->inode_bb_map
&&
799 (ext2fs_test_inode_bitmap(ctx
->inode_bb_map
,
802 * If the inode is in a bad block, offer to
805 problem
= PR_2_BB_INODE
;
806 } else if ((dot_state
> 1) &&
807 ((dirent
->name_len
& 0xFF) == 1) &&
808 (dirent
->name
[0] == '.')) {
810 * If there's a '.' entry in anything other
811 * than the first directory entry, it's a
812 * duplicate entry that should be removed.
814 problem
= PR_2_DUP_DOT
;
815 } else if ((dot_state
> 1) &&
816 ((dirent
->name_len
& 0xFF) == 2) &&
817 (dirent
->name
[0] == '.') &&
818 (dirent
->name
[1] == '.')) {
820 * If there's a '..' entry in anything other
821 * than the second directory entry, it's a
822 * duplicate entry that should be removed.
824 problem
= PR_2_DUP_DOT_DOT
;
825 } else if ((dot_state
> 1) &&
826 (dirent
->inode
== EXT2_ROOT_INO
)) {
828 * Don't allow links to the root directory.
829 * We check this specially to make sure we
830 * catch this error case even if the root
831 * directory hasn't been created yet.
833 problem
= PR_2_LINK_ROOT
;
834 } else if ((dot_state
> 1) &&
835 (dirent
->name_len
& 0xFF) == 0) {
837 * Don't allow zero-length directory names.
839 problem
= PR_2_NULL_NAME
;
843 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
848 ext2fs_unmark_valid(fs
);
849 if (problem
== PR_2_BAD_INO
)
855 * If the inode was marked as having bad fields in
856 * pass1, process it and offer to fix/clear it.
857 * (We wait until now so that we can display the
858 * pathname to the user.)
860 if (ctx
->inode_bad_map
&&
861 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
863 if (e2fsck_process_bad_inode(ctx
, ino
,
865 buf
+ fs
->blocksize
)) {
870 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
874 if (check_name(ctx
, dirent
, ino
, &cd
->pctx
))
877 if (check_filetype(ctx
, dirent
, ino
, &cd
->pctx
))
882 ext2fs_dirhash(dx_dir
->hashversion
, dirent
->name
,
883 (dirent
->name_len
& 0xFF),
884 fs
->super
->s_hash_seed
, &hash
, 0);
885 if (hash
< dx_db
->min_hash
)
886 dx_db
->min_hash
= hash
;
887 if (hash
> dx_db
->max_hash
)
888 dx_db
->max_hash
= hash
;
893 * If this is a directory, then mark its parent in its
894 * dir_info structure. If the parent field is already
895 * filled in, then this directory has more than one
896 * hard link. We assume the first link is correct,
897 * and ask the user if he/she wants to clear this one.
899 if ((dot_state
> 1) &&
900 (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
,
902 subdir
= e2fsck_get_dir_info(ctx
, dirent
->inode
);
904 cd
->pctx
.ino
= dirent
->inode
;
905 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
906 ctx
->flags
|= E2F_FLAG_ABORT
;
909 if (subdir
->parent
) {
910 cd
->pctx
.ino2
= subdir
->parent
;
911 if (fix_problem(ctx
, PR_2_LINK_DIR
,
919 subdir
->parent
= ino
;
922 ext2fs_icount_increment(ctx
->inode_count
, dirent
->inode
,
925 ctx
->fs_links_count
++;
926 ctx
->fs_total_count
++;
929 offset
+= dirent
->rec_len
;
931 } while (offset
< fs
->blocksize
);
938 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
939 db
->blockcnt
, dx_db
->type
,
940 dx_db
->min_hash
, dx_db
->max_hash
);
942 cd
->pctx
.dir
= cd
->pctx
.ino
;
943 if ((dx_db
->type
== DX_DIRBLOCK_ROOT
) ||
944 (dx_db
->type
== DX_DIRBLOCK_NODE
))
945 parse_int_node(fs
, db
, cd
, dx_dir
, buf
);
947 #endif /* ENABLE_HTREE */
948 if (offset
!= fs
->blocksize
) {
949 cd
->pctx
.num
= dirent
->rec_len
- fs
->blocksize
+ offset
;
950 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
951 dirent
->rec_len
= cd
->pctx
.num
;
956 cd
->pctx
.errcode
= ext2fs_write_dir_block(fs
, block_nr
, buf
);
957 if (cd
->pctx
.errcode
) {
958 if (!fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
,
960 ctx
->flags
|= E2F_FLAG_ABORT
;
964 ext2fs_mark_changed(fs
);
970 * This function is called to deallocate a block, and is an interator
971 * functioned called by deallocate inode via ext2fs_iterate_block().
973 static int deallocate_inode_block(ext2_filsys fs
,
975 e2_blkcnt_t blockcnt
,
980 e2fsck_t ctx
= (e2fsck_t
) priv_data
;
982 if (HOLE_BLKADDR(*block_nr
))
984 ext2fs_unmark_block_bitmap(ctx
->block_found_map
, *block_nr
);
985 ext2fs_block_alloc_stats(fs
, *block_nr
, -1);
990 * This fuction deallocates an inode
992 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
)
994 ext2_filsys fs
= ctx
->fs
;
995 struct ext2_inode inode
;
996 struct problem_context pctx
;
999 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 0);
1000 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
1001 inode
.i_links_count
= 0;
1002 inode
.i_dtime
= time(0);
1003 e2fsck_write_inode(ctx
, ino
, &inode
, "deallocate_inode");
1004 clear_problem_context(&pctx
);
1008 * Fix up the bitmaps...
1010 e2fsck_read_bitmaps(ctx
);
1011 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, ino
);
1012 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, ino
);
1013 if (ctx
->inode_bad_map
)
1014 ext2fs_unmark_inode_bitmap(ctx
->inode_bad_map
, ino
);
1015 ext2fs_inode_alloc_stats2(fs
, ino
, -1, LINUX_S_ISDIR(inode
.i_mode
));
1017 if (inode
.i_file_acl
&&
1018 (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
1019 pctx
.errcode
= ext2fs_adjust_ea_refcount(fs
, inode
.i_file_acl
,
1020 block_buf
, -1, &count
);
1021 if (pctx
.errcode
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
1026 pctx
.blk
= inode
.i_file_acl
;
1027 fix_problem(ctx
, PR_2_ADJ_EA_REFCOUNT
, &pctx
);
1028 ctx
->flags
|= E2F_FLAG_ABORT
;
1032 ext2fs_unmark_block_bitmap(ctx
->block_found_map
,
1034 ext2fs_block_alloc_stats(fs
, inode
.i_file_acl
, -1);
1036 inode
.i_file_acl
= 0;
1039 if (!ext2fs_inode_has_valid_blocks(&inode
))
1042 if (LINUX_S_ISREG(inode
.i_mode
) &&
1043 (inode
.i_size_high
|| inode
.i_size
& 0x80000000UL
))
1046 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
1047 deallocate_inode_block
, ctx
);
1049 fix_problem(ctx
, PR_2_DEALLOC_INODE
, &pctx
);
1050 ctx
->flags
|= E2F_FLAG_ABORT
;
1056 * This fuction clears the htree flag on an inode
1058 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
)
1060 struct ext2_inode inode
;
1062 e2fsck_read_inode(ctx
, ino
, &inode
, "clear_htree");
1063 inode
.i_flags
= inode
.i_flags
& ~EXT2_INDEX_FL
;
1064 e2fsck_write_inode(ctx
, ino
, &inode
, "clear_htree");
1065 if (ctx
->dirs_to_hash
)
1066 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
1070 extern int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
1071 ext2_ino_t ino
, char *buf
)
1073 ext2_filsys fs
= ctx
->fs
;
1074 struct ext2_inode inode
;
1075 int inode_modified
= 0;
1076 unsigned char *frag
, *fsize
;
1077 struct problem_context pctx
;
1080 e2fsck_read_inode(ctx
, ino
, &inode
, "process_bad_inode");
1082 clear_problem_context(&pctx
);
1085 pctx
.inode
= &inode
;
1087 if (!LINUX_S_ISDIR(inode
.i_mode
) && !LINUX_S_ISREG(inode
.i_mode
) &&
1088 !LINUX_S_ISCHR(inode
.i_mode
) && !LINUX_S_ISBLK(inode
.i_mode
) &&
1089 !LINUX_S_ISLNK(inode
.i_mode
) && !LINUX_S_ISFIFO(inode
.i_mode
) &&
1090 !(LINUX_S_ISSOCK(inode
.i_mode
)))
1091 problem
= PR_2_BAD_MODE
;
1092 else if (LINUX_S_ISCHR(inode
.i_mode
)
1093 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1094 problem
= PR_2_BAD_CHAR_DEV
;
1095 else if (LINUX_S_ISBLK(inode
.i_mode
)
1096 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1097 problem
= PR_2_BAD_BLOCK_DEV
;
1098 else if (LINUX_S_ISFIFO(inode
.i_mode
)
1099 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1100 problem
= PR_2_BAD_FIFO
;
1101 else if (LINUX_S_ISSOCK(inode
.i_mode
)
1102 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1103 problem
= PR_2_BAD_SOCKET
;
1104 else if (LINUX_S_ISLNK(inode
.i_mode
)
1105 && !e2fsck_pass1_check_symlink(fs
, &inode
, buf
)) {
1106 problem
= PR_2_INVALID_SYMLINK
;
1110 if (fix_problem(ctx
, problem
, &pctx
)) {
1111 deallocate_inode(ctx
, ino
, 0);
1112 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
1119 if (inode
.i_faddr
&&
1120 fix_problem(ctx
, PR_2_FADDR_ZERO
, &pctx
)) {
1125 switch (fs
->super
->s_creator_os
) {
1127 frag
= &inode
.osd2
.linux2
.l_i_frag
;
1128 fsize
= &inode
.osd2
.linux2
.l_i_fsize
;
1131 frag
= &inode
.osd2
.hurd2
.h_i_frag
;
1132 fsize
= &inode
.osd2
.hurd2
.h_i_fsize
;
1135 frag
= &inode
.osd2
.masix2
.m_i_frag
;
1136 fsize
= &inode
.osd2
.masix2
.m_i_fsize
;
1141 if (frag
&& *frag
) {
1143 if (fix_problem(ctx
, PR_2_FRAG_ZERO
, &pctx
)) {
1149 if (fsize
&& *fsize
) {
1151 if (fix_problem(ctx
, PR_2_FSIZE_ZERO
, &pctx
)) {
1158 if (inode
.i_file_acl
&&
1159 !(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
) &&
1160 fix_problem(ctx
, PR_2_FILE_ACL_ZERO
, &pctx
)) {
1161 inode
.i_file_acl
= 0;
1164 if (inode
.i_file_acl
&&
1165 ((inode
.i_file_acl
< fs
->super
->s_first_data_block
) ||
1166 (inode
.i_file_acl
>= fs
->super
->s_blocks_count
)) &&
1167 fix_problem(ctx
, PR_2_FILE_ACL_BAD
, &pctx
)) {
1168 inode
.i_file_acl
= 0;
1171 if (inode
.i_dir_acl
&&
1172 LINUX_S_ISDIR(inode
.i_mode
) &&
1173 fix_problem(ctx
, PR_2_DIR_ACL_ZERO
, &pctx
)) {
1174 inode
.i_dir_acl
= 0;
1178 e2fsck_write_inode(ctx
, ino
, &inode
, "process_bad_inode");
1184 * allocate_dir_block --- this function allocates a new directory
1185 * block for a particular inode; this is done if a directory has
1186 * a "hole" in it, or if a directory has a illegal block number
1187 * that was zeroed out and now needs to be replaced.
1189 static int allocate_dir_block(e2fsck_t ctx
,
1190 struct ext2_db_entry
*db
,
1191 char *buf
, struct problem_context
*pctx
)
1193 ext2_filsys fs
= ctx
->fs
;
1196 struct ext2_inode inode
;
1198 if (fix_problem(ctx
, PR_2_DIRECTORY_HOLE
, pctx
) == 0)
1202 * Read the inode and block bitmaps in; we'll be messing with
1205 e2fsck_read_bitmaps(ctx
);
1208 * First, find a free block
1210 pctx
->errcode
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
, &blk
);
1211 if (pctx
->errcode
) {
1212 pctx
->str
= "ext2fs_new_block";
1213 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1216 ext2fs_mark_block_bitmap(ctx
->block_found_map
, blk
);
1217 ext2fs_mark_block_bitmap(fs
->block_map
, blk
);
1218 ext2fs_mark_bb_dirty(fs
);
1221 * Now let's create the actual data block for the inode
1224 pctx
->errcode
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
1226 pctx
->errcode
= ext2fs_new_dir_block(fs
, db
->ino
,
1227 EXT2_ROOT_INO
, &block
);
1229 if (pctx
->errcode
) {
1230 pctx
->str
= "ext2fs_new_dir_block";
1231 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1235 pctx
->errcode
= ext2fs_write_dir_block(fs
, blk
, block
);
1236 ext2fs_free_mem((void **) &block
);
1237 if (pctx
->errcode
) {
1238 pctx
->str
= "ext2fs_write_dir_block";
1239 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1244 * Update the inode block count
1246 e2fsck_read_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1247 inode
.i_blocks
+= fs
->blocksize
/ 512;
1248 if (inode
.i_size
< (db
->blockcnt
+1) * fs
->blocksize
)
1249 inode
.i_size
= (db
->blockcnt
+1) * fs
->blocksize
;
1250 e2fsck_write_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1253 * Finally, update the block pointers for the inode
1256 pctx
->errcode
= ext2fs_block_iterate2(fs
, db
->ino
, BLOCK_FLAG_HOLE
,
1257 0, update_dir_block
, db
);
1258 if (pctx
->errcode
) {
1259 pctx
->str
= "ext2fs_block_iterate";
1260 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1268 * This is a helper function for allocate_dir_block().
1270 static int update_dir_block(ext2_filsys fs
,
1272 e2_blkcnt_t blockcnt
,
1277 struct ext2_db_entry
*db
;
1279 db
= (struct ext2_db_entry
*) priv_data
;
1280 if (db
->blockcnt
== (int) blockcnt
) {
1281 *block_nr
= db
->blk
;
1282 return BLOCK_CHANGED
;