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
44 #define _GNU_SOURCE 1 /* get strnlen() */
52 #ifdef NO_INLINE_FUNCS
55 #define _INLINE_ inline
58 /* #define DX_DEBUG */
61 * Keeps track of how many times an inode is referenced.
63 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
);
64 static int check_dir_block(ext2_filsys fs
,
65 struct ext2_db_entry2
*dir_blocks_info
,
67 static int allocate_dir_block(e2fsck_t ctx
,
68 struct ext2_db_entry2
*dir_blocks_info
,
69 char *buf
, struct problem_context
*pctx
);
70 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
);
71 static int htree_depth(struct dx_dir_info
*dx_dir
,
72 struct dx_dirblock_info
*dx_db
);
73 static EXT2_QSORT_TYPE
special_dir_block_cmp(const void *a
, const void *b
);
75 struct check_dir_struct
{
77 struct problem_context pctx
;
82 void e2fsck_pass2(e2fsck_t ctx
)
84 struct ext2_super_block
*sb
= ctx
->fs
->super
;
85 struct problem_context pctx
;
86 ext2_filsys fs
= ctx
->fs
;
89 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
;
94 unsigned int save_type
;
100 init_resource_track(&rtrack
, ctx
->fs
->io
);
101 clear_problem_context(&cd
.pctx
);
104 mtrace_print("Pass 2");
107 if (!(ctx
->options
& E2F_OPT_PREEN
))
108 fix_problem(ctx
, PR_2_PASS_HEADER
, &cd
.pctx
);
110 e2fsck_setup_tdb_icount(ctx
, EXT2_ICOUNT_OPT_INCREMENT
,
112 if (ctx
->inode_count
)
115 e2fsck_set_bitmap_type(fs
, EXT2FS_BMAP64_RBTREE
,
116 "inode_count", &save_type
);
117 cd
.pctx
.errcode
= ext2fs_create_icount2(fs
,
118 EXT2_ICOUNT_OPT_INCREMENT
,
119 0, ctx
->inode_link_info
,
121 fs
->default_bitmap_type
= save_type
;
123 if (cd
.pctx
.errcode
) {
124 fix_problem(ctx
, PR_2_ALLOCATE_ICOUNT
, &cd
.pctx
);
125 ctx
->flags
|= E2F_FLAG_ABORT
;
128 buf
= (char *) e2fsck_allocate_memory(ctx
, 2*fs
->blocksize
,
129 "directory scan buffer");
132 * Set up the parent pointer for the root directory, if
133 * present. (If the root directory is not present, we will
134 * create it in pass 3.)
136 (void) e2fsck_dir_info_set_parent(ctx
, EXT2_ROOT_INO
, EXT2_ROOT_INO
);
141 cd
.max
= ext2fs_dblist_count2(fs
->dblist
);
144 (void) (ctx
->progress
)(ctx
, 2, 0, cd
.max
);
146 if (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
)
147 ext2fs_dblist_sort2(fs
->dblist
, special_dir_block_cmp
);
149 cd
.pctx
.errcode
= ext2fs_dblist_iterate2(fs
->dblist
, check_dir_block
,
151 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
|| ctx
->flags
& E2F_FLAG_RESTART
)
154 if (ctx
->flags
& E2F_FLAG_RESTART_LATER
) {
155 ctx
->flags
|= E2F_FLAG_RESTART
;
159 if (cd
.pctx
.errcode
) {
160 fix_problem(ctx
, PR_2_DBLIST_ITERATE
, &cd
.pctx
);
161 ctx
->flags
|= E2F_FLAG_ABORT
;
166 for (i
=0; (dx_dir
= e2fsck_dx_dir_info_iter(ctx
, &i
)) != 0;) {
167 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
169 if (e2fsck_dir_will_be_rehashed(ctx
, dx_dir
->ino
) ||
170 dx_dir
->numblocks
== 0)
172 clear_problem_context(&pctx
);
174 pctx
.dir
= dx_dir
->ino
;
175 dx_db
= dx_dir
->dx_block
;
176 if (dx_db
->flags
& DX_FLAG_REFERENCED
)
177 dx_db
->flags
|= DX_FLAG_DUP_REF
;
179 dx_db
->flags
|= DX_FLAG_REFERENCED
;
181 * Find all of the first and last leaf blocks, and
182 * update their parent's min and max hash values
184 for (b
=0, dx_db
= dx_dir
->dx_block
;
185 b
< dx_dir
->numblocks
;
187 if ((dx_db
->type
!= DX_DIRBLOCK_LEAF
) ||
188 !(dx_db
->flags
& (DX_FLAG_FIRST
| DX_FLAG_LAST
)))
190 dx_parent
= &dx_dir
->dx_block
[dx_db
->parent
];
192 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
194 if (dx_db
->flags
& DX_FLAG_FIRST
)
195 dx_parent
->min_hash
= dx_db
->min_hash
;
197 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
199 if (dx_db
->flags
& DX_FLAG_LAST
)
200 dx_parent
->max_hash
= dx_db
->max_hash
;
203 for (b
=0, dx_db
= dx_dir
->dx_block
;
204 b
< dx_dir
->numblocks
;
207 pctx
.group
= dx_db
->parent
;
209 if (!(dx_db
->flags
& DX_FLAG_FIRST
) &&
210 (dx_db
->min_hash
< dx_db
->node_min_hash
)) {
211 pctx
.blk
= dx_db
->min_hash
;
212 pctx
.blk2
= dx_db
->node_min_hash
;
213 code
= PR_2_HTREE_MIN_HASH
;
214 fix_problem(ctx
, code
, &pctx
);
217 if (dx_db
->type
== DX_DIRBLOCK_LEAF
) {
218 depth
= htree_depth(dx_dir
, dx_db
);
219 if (depth
!= dx_dir
->depth
) {
220 pctx
.num
= dx_dir
->depth
;
221 code
= PR_2_HTREE_BAD_DEPTH
;
222 fix_problem(ctx
, code
, &pctx
);
227 * This test doesn't apply for the root block
231 (dx_db
->max_hash
> dx_db
->node_max_hash
)) {
232 pctx
.blk
= dx_db
->max_hash
;
233 pctx
.blk2
= dx_db
->node_max_hash
;
234 code
= PR_2_HTREE_MAX_HASH
;
235 fix_problem(ctx
, code
, &pctx
);
238 if (!(dx_db
->flags
& DX_FLAG_REFERENCED
)) {
239 code
= PR_2_HTREE_NOTREF
;
240 fix_problem(ctx
, code
, &pctx
);
242 } else if (dx_db
->flags
& DX_FLAG_DUP_REF
) {
243 code
= PR_2_HTREE_DUPREF
;
244 fix_problem(ctx
, code
, &pctx
);
248 if (bad_dir
&& fix_problem(ctx
, PR_2_HTREE_CLEAR
, &pctx
)) {
249 clear_htree(ctx
, dx_dir
->ino
);
250 dx_dir
->numblocks
= 0;
253 e2fsck_free_dx_dir_info(ctx
);
255 ext2fs_free_mem(&buf
);
256 ext2fs_free_dblist(fs
->dblist
);
258 if (ctx
->inode_bad_map
) {
259 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
260 ctx
->inode_bad_map
= 0;
262 if (ctx
->inode_reg_map
) {
263 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
264 ctx
->inode_reg_map
= 0;
267 clear_problem_context(&pctx
);
268 if (ctx
->large_files
) {
269 if (!(sb
->s_feature_ro_compat
&
270 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
) &&
271 fix_problem(ctx
, PR_2_FEATURE_LARGE_FILES
, &pctx
)) {
272 sb
->s_feature_ro_compat
|=
273 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
274 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
275 ext2fs_mark_super_dirty(fs
);
277 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
278 fix_problem(ctx
, PR_1_FS_REV_LEVEL
, &pctx
)) {
279 ext2fs_update_dynamic_rev(fs
);
280 ext2fs_mark_super_dirty(fs
);
284 print_resource_track(ctx
, _("Pass 2"), &rtrack
, fs
->io
);
287 #define MAX_DEPTH 32000
288 static int htree_depth(struct dx_dir_info
*dx_dir
,
289 struct dx_dirblock_info
*dx_db
)
293 while (dx_db
->type
!= DX_DIRBLOCK_ROOT
&& depth
< MAX_DEPTH
) {
294 dx_db
= &dx_dir
->dx_block
[dx_db
->parent
];
300 static int dict_de_cmp(const void *a
, const void *b
)
302 const struct ext2_dir_entry
*de_a
, *de_b
;
305 de_a
= (const struct ext2_dir_entry
*) a
;
306 a_len
= ext2fs_dirent_name_len(de_a
);
307 de_b
= (const struct ext2_dir_entry
*) b
;
308 b_len
= ext2fs_dirent_name_len(de_b
);
311 return (a_len
- b_len
);
313 return strncmp(de_a
->name
, de_b
->name
, a_len
);
317 * This is special sort function that makes sure that directory blocks
318 * with a dirblock of zero are sorted to the beginning of the list.
319 * This guarantees that the root node of the htree directories are
320 * processed first, so we know what hash version to use.
322 static EXT2_QSORT_TYPE
special_dir_block_cmp(const void *a
, const void *b
)
324 const struct ext2_db_entry2
*db_a
=
325 (const struct ext2_db_entry2
*) a
;
326 const struct ext2_db_entry2
*db_b
=
327 (const struct ext2_db_entry2
*) b
;
329 if (db_a
->blockcnt
&& !db_b
->blockcnt
)
332 if (!db_a
->blockcnt
&& db_b
->blockcnt
)
335 if (db_a
->blk
!= db_b
->blk
)
336 return (int) (db_a
->blk
- db_b
->blk
);
338 if (db_a
->ino
!= db_b
->ino
)
339 return (int) (db_a
->ino
- db_b
->ino
);
341 return (int) (db_a
->blockcnt
- db_b
->blockcnt
);
346 * Make sure the first entry in the directory is '.', and that the
347 * directory entry is sane.
349 static int check_dot(e2fsck_t ctx
,
350 struct ext2_dir_entry
*dirent
,
351 ext2_ino_t ino
, struct problem_context
*pctx
)
353 struct ext2_dir_entry
*nextdir
;
354 unsigned int rec_len
, new_len
;
357 problem_t problem
= 0;
360 problem
= PR_2_MISSING_DOT
;
361 else if ((ext2fs_dirent_name_len(dirent
) != 1) ||
362 (dirent
->name
[0] != '.'))
363 problem
= PR_2_1ST_NOT_DOT
;
364 else if (dirent
->name
[1] != '\0')
365 problem
= PR_2_DOT_NULL_TERM
;
367 (void) ext2fs_get_rec_len(ctx
->fs
, dirent
, &rec_len
);
369 if (fix_problem(ctx
, problem
, pctx
)) {
371 rec_len
= dirent
->rec_len
= 12;
373 ext2fs_dirent_set_name_len(dirent
, 1);
374 ext2fs_dirent_set_file_type(dirent
, EXT2_FT_UNKNOWN
);
375 dirent
->name
[0] = '.';
376 dirent
->name
[1] = '\0';
381 if (dirent
->inode
!= ino
) {
382 if (fix_problem(ctx
, PR_2_BAD_INODE_DOT
, pctx
)) {
388 new_len
= rec_len
- 12;
391 fix_problem(ctx
, PR_2_SPLIT_DOT
, pctx
)) {
392 nextdir
= (struct ext2_dir_entry
*)
393 ((char *) dirent
+ 12);
394 dirent
->rec_len
= 12;
395 (void) ext2fs_set_rec_len(ctx
->fs
, new_len
,
398 ext2fs_dirent_set_name_len(nextdir
, 0);
399 ext2fs_dirent_set_file_type(nextdir
,
409 * Make sure the second entry in the directory is '..', and that the
410 * directory entry is sane. We do not check the inode number of '..'
411 * here; this gets done in pass 3.
413 static int check_dotdot(e2fsck_t ctx
,
414 struct ext2_dir_entry
*dirent
,
415 ext2_ino_t ino
, struct problem_context
*pctx
)
417 problem_t problem
= 0;
418 unsigned int rec_len
;
421 problem
= PR_2_MISSING_DOT_DOT
;
422 else if ((ext2fs_dirent_name_len(dirent
) != 2) ||
423 (dirent
->name
[0] != '.') ||
424 (dirent
->name
[1] != '.'))
425 problem
= PR_2_2ND_NOT_DOT_DOT
;
426 else if (dirent
->name
[2] != '\0')
427 problem
= PR_2_DOT_DOT_NULL_TERM
;
429 (void) ext2fs_get_rec_len(ctx
->fs
, dirent
, &rec_len
);
431 if (fix_problem(ctx
, problem
, pctx
)) {
433 dirent
->rec_len
= 12;
435 * Note: we don't have the parent inode just
436 * yet, so we will fill it in with the root
437 * inode. This will get fixed in pass 3.
439 dirent
->inode
= EXT2_ROOT_INO
;
440 ext2fs_dirent_set_name_len(dirent
, 2);
441 ext2fs_dirent_set_file_type(dirent
, EXT2_FT_UNKNOWN
);
442 dirent
->name
[0] = '.';
443 dirent
->name
[1] = '.';
444 dirent
->name
[2] = '\0';
449 if (e2fsck_dir_info_set_dotdot(ctx
, ino
, dirent
->inode
)) {
450 fix_problem(ctx
, PR_2_NO_DIRINFO
, pctx
);
457 * Check to make sure a directory entry doesn't contain any illegal
460 static int check_name(e2fsck_t ctx
,
461 struct ext2_dir_entry
*dirent
,
462 ext2_ino_t dir_ino
EXT2FS_ATTR((unused
)),
463 struct problem_context
*pctx
)
469 for ( i
= 0; i
< ext2fs_dirent_name_len(dirent
); i
++) {
470 if (dirent
->name
[i
] == '/' || dirent
->name
[i
] == '\0') {
472 fixup
= fix_problem(ctx
, PR_2_BAD_NAME
, pctx
);
475 dirent
->name
[i
] = '.';
484 * Check the directory filetype (if present)
486 static _INLINE_
int check_filetype(e2fsck_t ctx
,
487 struct ext2_dir_entry
*dirent
,
488 ext2_ino_t dir_ino
EXT2FS_ATTR((unused
)),
489 struct problem_context
*pctx
)
491 int filetype
= ext2fs_dirent_file_type(dirent
);
492 int should_be
= EXT2_FT_UNKNOWN
;
493 struct ext2_inode inode
;
495 if (!(ctx
->fs
->super
->s_feature_incompat
&
496 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
498 !fix_problem(ctx
, PR_2_CLEAR_FILETYPE
, pctx
))
500 ext2fs_dirent_set_file_type(dirent
, EXT2_FT_UNKNOWN
);
504 if (ext2fs_test_inode_bitmap2(ctx
->inode_dir_map
, dirent
->inode
)) {
505 should_be
= EXT2_FT_DIR
;
506 } else if (ext2fs_test_inode_bitmap2(ctx
->inode_reg_map
,
508 should_be
= EXT2_FT_REG_FILE
;
509 } else if (ctx
->inode_bad_map
&&
510 ext2fs_test_inode_bitmap2(ctx
->inode_bad_map
,
514 e2fsck_read_inode(ctx
, dirent
->inode
, &inode
,
516 should_be
= ext2_file_type(inode
.i_mode
);
518 if (filetype
== should_be
)
520 pctx
->num
= should_be
;
522 if (fix_problem(ctx
, filetype
? PR_2_BAD_FILETYPE
: PR_2_SET_FILETYPE
,
526 ext2fs_dirent_set_file_type(dirent
, should_be
);
531 static void parse_int_node(ext2_filsys fs
,
532 struct ext2_db_entry2
*db
,
533 struct check_dir_struct
*cd
,
534 struct dx_dir_info
*dx_dir
,
535 char *block_buf
, int failed_csum
)
537 struct ext2_dx_root_info
*root
;
538 struct ext2_dx_entry
*ent
;
539 struct ext2_dx_countlimit
*limit
;
540 struct dx_dirblock_info
*dx_db
;
541 int i
, expect_limit
, count
;
543 ext2_dirhash_t min_hash
= 0xffffffff;
544 ext2_dirhash_t max_hash
= 0;
545 ext2_dirhash_t hash
= 0, prev_hash
;
548 if (db
->blockcnt
== 0) {
549 root
= (struct ext2_dx_root_info
*) (block_buf
+ 24);
552 printf("Root node dump:\n");
553 printf("\t Reserved zero: %u\n", root
->reserved_zero
);
554 printf("\t Hash Version: %d\n", root
->hash_version
);
555 printf("\t Info length: %d\n", root
->info_length
);
556 printf("\t Indirect levels: %d\n", root
->indirect_levels
);
557 printf("\t Flags: %d\n", root
->unused_flags
);
560 ent
= (struct ext2_dx_entry
*) (block_buf
+ 24 + root
->info_length
);
563 (e2fsck_dir_will_be_rehashed(cd
->ctx
, cd
->pctx
.ino
) ||
564 fix_problem(cd
->ctx
, PR_2_HTREE_ROOT_CSUM_INVALID
,
568 ent
= (struct ext2_dx_entry
*) (block_buf
+8);
571 (e2fsck_dir_will_be_rehashed(cd
->ctx
, cd
->pctx
.ino
) ||
572 fix_problem(cd
->ctx
, PR_2_HTREE_NODE_CSUM_INVALID
,
577 limit
= (struct ext2_dx_countlimit
*) ent
;
580 printf("Number of entries (count): %d\n",
581 ext2fs_le16_to_cpu(limit
->count
));
582 printf("Number of entries (limit): %d\n",
583 ext2fs_le16_to_cpu(limit
->limit
));
586 count
= ext2fs_le16_to_cpu(limit
->count
);
587 if (EXT2_HAS_RO_COMPAT_FEATURE(fs
->super
,
588 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
))
589 csum_size
= sizeof(struct ext2_dx_tail
);
590 expect_limit
= (fs
->blocksize
-
591 (csum_size
+ ((char *) ent
- block_buf
))) /
592 sizeof(struct ext2_dx_entry
);
593 if (ext2fs_le16_to_cpu(limit
->limit
) != expect_limit
) {
594 cd
->pctx
.num
= ext2fs_le16_to_cpu(limit
->limit
);
595 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_LIMIT
, &cd
->pctx
))
598 if (count
> expect_limit
) {
599 cd
->pctx
.num
= count
;
600 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_COUNT
, &cd
->pctx
))
602 count
= expect_limit
;
605 for (i
=0; i
< count
; i
++) {
607 hash
= i
? (ext2fs_le32_to_cpu(ent
[i
].hash
) & ~1) : 0;
609 printf("Entry #%d: Hash 0x%08x, block %u\n", i
,
610 hash
, ext2fs_le32_to_cpu(ent
[i
].block
));
612 blk
= ext2fs_le32_to_cpu(ent
[i
].block
) & 0x0ffffff;
613 /* Check to make sure the block is valid */
614 if (blk
>= (blk_t
) dx_dir
->numblocks
) {
616 if (fix_problem(cd
->ctx
, PR_2_HTREE_BADBLK
,
621 if (hash
< prev_hash
&&
622 fix_problem(cd
->ctx
, PR_2_HTREE_HASH_ORDER
, &cd
->pctx
))
624 dx_db
= &dx_dir
->dx_block
[blk
];
625 if (dx_db
->flags
& DX_FLAG_REFERENCED
) {
626 dx_db
->flags
|= DX_FLAG_DUP_REF
;
628 dx_db
->flags
|= DX_FLAG_REFERENCED
;
629 dx_db
->parent
= db
->blockcnt
;
635 dx_db
->node_min_hash
= hash
;
637 dx_db
->node_max_hash
=
638 ext2fs_le32_to_cpu(ent
[i
+1].hash
) & ~1;
640 dx_db
->node_max_hash
= 0xfffffffe;
641 dx_db
->flags
|= DX_FLAG_LAST
;
644 dx_db
->flags
|= DX_FLAG_FIRST
;
647 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
648 db
->blockcnt
, min_hash
, max_hash
);
650 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
651 dx_db
->min_hash
= min_hash
;
652 dx_db
->max_hash
= max_hash
;
656 clear_htree(cd
->ctx
, cd
->pctx
.ino
);
657 dx_dir
->numblocks
= 0;
658 e2fsck_rehash_dir_later(cd
->ctx
, cd
->pctx
.ino
);
660 #endif /* ENABLE_HTREE */
663 * Given a busted directory, try to salvage it somehow.
666 static void salvage_directory(ext2_filsys fs
,
667 struct ext2_dir_entry
*dirent
,
668 struct ext2_dir_entry
*prev
,
669 unsigned int *offset
,
670 unsigned int block_len
)
672 char *cp
= (char *) dirent
;
674 unsigned int rec_len
, prev_rec_len
;
675 unsigned int name_len
= ext2fs_dirent_name_len(dirent
);
677 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
678 left
= block_len
- *offset
- rec_len
;
681 * Special case of directory entry of size 8: copy what's left
682 * of the directory block up to cover up the invalid hole.
684 if ((left
>= 12) && (rec_len
== 8)) {
685 memmove(cp
, cp
+8, left
);
686 memset(cp
+ left
, 0, 8);
690 * If the directory entry overruns the end of the directory
691 * block, and the name is small enough to fit, then adjust the
695 ((int) rec_len
+ left
> 8) &&
696 ((int) name_len
+ 8 <= (int) rec_len
+ left
) &&
697 dirent
->inode
<= fs
->super
->s_inodes_count
&&
698 strnlen(dirent
->name
, name_len
) == name_len
) {
699 (void) ext2fs_set_rec_len(fs
, (int) rec_len
+ left
, dirent
);
703 * If the record length of the directory entry is a multiple
704 * of four, and not too big, such that it is valid, let the
705 * previous directory entry absorb the invalid one.
707 if (prev
&& rec_len
&& (rec_len
% 4) == 0 &&
708 (*offset
+ rec_len
<= block_len
)) {
709 (void) ext2fs_get_rec_len(fs
, prev
, &prev_rec_len
);
710 prev_rec_len
+= rec_len
;
711 (void) ext2fs_set_rec_len(fs
, prev_rec_len
, prev
);
716 * Default salvage method --- kill all of the directory
717 * entries for the rest of the block. We will either try to
718 * absorb it into the previous directory entry, or create a
719 * new empty directory entry the rest of the directory block.
722 (void) ext2fs_get_rec_len(fs
, prev
, &prev_rec_len
);
723 prev_rec_len
+= block_len
- *offset
;
724 (void) ext2fs_set_rec_len(fs
, prev_rec_len
, prev
);
725 *offset
= fs
->blocksize
;
727 rec_len
= block_len
- *offset
;
728 (void) ext2fs_set_rec_len(fs
, rec_len
, dirent
);
729 ext2fs_dirent_set_name_len(dirent
, 0);
730 ext2fs_dirent_set_file_type(dirent
, EXT2_FT_UNKNOWN
);
735 static int is_last_entry(ext2_filsys fs
, int inline_data_size
,
736 unsigned int offset
, int csum_size
)
738 if (inline_data_size
)
739 return (offset
< inline_data_size
);
741 return (offset
< fs
->blocksize
- csum_size
);
744 #define NEXT_DIRENT(d) ((void *)((char *)(d) + (d)->rec_len))
745 static errcode_t
insert_dirent_tail(ext2_filsys fs
, void *dirbuf
)
747 struct ext2_dir_entry
*d
;
749 struct ext2_dir_entry_tail
*t
;
752 top
= EXT2_DIRENT_TAIL(dirbuf
, fs
->blocksize
);
754 while (d
->rec_len
&& !(d
->rec_len
& 0x3) && NEXT_DIRENT(d
) <= top
)
758 size_t min_size
= EXT2_DIR_REC_LEN(
759 ext2fs_dirent_name_len(dirbuf
));
760 if (min_size
> top
- (void *)d
)
761 return EXT2_ET_DIR_NO_SPACE_FOR_CSUM
;
762 d
->rec_len
= top
- (void *)d
;
765 t
= (struct ext2_dir_entry_tail
*)top
;
766 if (t
->det_reserved_zero1
||
767 t
->det_rec_len
!= sizeof(struct ext2_dir_entry_tail
) ||
768 t
->det_reserved_name_len
!= EXT2_DIR_NAME_LEN_CSUM
)
769 ext2fs_initialize_dirent_tail(fs
, t
);
775 static errcode_t
fix_inline_dir_size(e2fsck_t ctx
, ext2_ino_t ino
,
776 size_t *inline_data_size
,
777 struct problem_context
*pctx
,
780 ext2_filsys fs
= ctx
->fs
;
781 struct ext2_inode inode
;
782 size_t new_size
, old_size
;
785 old_size
= *inline_data_size
;
786 new_size
= old_size
+ (4 - (old_size
& 3));
787 memset(buf
+ old_size
, 0, new_size
- old_size
);
788 retval
= ext2fs_inline_data_set(fs
, ino
, 0, buf
, new_size
);
789 if (retval
== EXT2_ET_INLINE_DATA_NO_SPACE
) {
791 retval
= ext2fs_inline_data_set(fs
, ino
, 0, buf
, new_size
);
793 if (fix_problem(ctx
, PR_2_FIX_INLINE_DIR_FAILED
,
801 if (fix_problem(ctx
, PR_2_FIX_INLINE_DIR_FAILED
,
810 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
814 retval
= ext2fs_inode_size_set(fs
, &inode
, new_size
);
818 inode
.i_flags
&= ~EXT4_INLINE_DATA_FL
;
819 retval
= ext2fs_write_inode(fs
, ino
, &inode
);
822 *inline_data_size
= new_size
;
828 static int check_dir_block(ext2_filsys fs
,
829 struct ext2_db_entry2
*db
,
832 struct dx_dir_info
*dx_dir
;
834 struct dx_dirblock_info
*dx_db
= 0;
835 #endif /* ENABLE_HTREE */
836 struct ext2_dir_entry
*dirent
, *prev
, dot
, dotdot
;
838 unsigned int offset
= 0;
839 int dir_modified
= 0;
841 unsigned int rec_len
;
842 blk64_t block_nr
= db
->blk
;
843 ext2_ino_t ino
= db
->ino
;
844 ext2_ino_t subdir_parent
;
846 struct check_dir_struct
*cd
;
850 struct ext2_dx_root_info
*root
;
851 struct ext2_dx_countlimit
*limit
;
852 static dict_t de_dict
;
853 struct problem_context pctx
;
856 int dx_csum_size
= 0, de_csum_size
= 0;
859 size_t inline_data_size
= 0;
862 cd
= (struct check_dir_struct
*) priv_data
;
866 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
|| ctx
->flags
& E2F_FLAG_RESTART
)
869 if (ctx
->progress
&& (ctx
->progress
)(ctx
, 2, cd
->count
++, cd
->max
))
872 if (EXT2_HAS_RO_COMPAT_FEATURE(fs
->super
,
873 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
)) {
874 dx_csum_size
= sizeof(struct ext2_dx_tail
);
875 de_csum_size
= sizeof(struct ext2_dir_entry_tail
);
878 if (EXT2_HAS_INCOMPAT_FEATURE(fs
->super
,
879 EXT2_FEATURE_INCOMPAT_FILETYPE
))
880 filetype
= EXT2_FT_DIR
<< 8;
883 * Make sure the inode is still in use (could have been
884 * deleted in the duplicate/bad blocks pass.
886 if (!(ext2fs_test_inode_bitmap2(ctx
->inode_used_map
, ino
)))
890 cd
->pctx
.blk
= block_nr
;
891 cd
->pctx
.blkcount
= db
->blockcnt
;
896 if (EXT2_HAS_INCOMPAT_FEATURE(fs
->super
,
897 EXT4_FEATURE_INCOMPAT_INLINE_DATA
)) {
900 ec
= ext2fs_inline_data_size(fs
, ino
, &inline_data_size
);
901 if (ec
&& ec
!= EXT2_ET_NO_INLINE_DATA
)
905 if (db
->blk
== 0 && !inline_data_size
) {
906 if (allocate_dir_block(ctx
, db
, buf
, &cd
->pctx
))
916 if (ctx
->dirs_to_hash
&&
917 ext2fs_u32_list_test(ctx
->dirs_to_hash
, ino
))
921 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr
,
925 ehandler_operation(_("reading directory block"));
926 if (inline_data_size
) {
927 cd
->pctx
.errcode
= ext2fs_inline_data_get(fs
, ino
, 0, buf
, 0);
928 if (cd
->pctx
.errcode
)
929 goto inline_read_fail
;
930 #ifdef WORDS_BIGENDIAN
931 *((__u32
*)buf
) = ext2fs_le32_to_cpu(*((__u32
*)buf
));
932 cd
->pctx
.errcode
= ext2fs_dirent_swab_in2(fs
,
933 buf
+ EXT4_INLINE_DATA_DOTDOT_SIZE
,
934 inline_data_size
- EXT4_INLINE_DATA_DOTDOT_SIZE
,
938 cd
->pctx
.errcode
= ext2fs_read_dir_block4(fs
, block_nr
,
942 pctx
.num
= inline_data_size
;
943 if ((inline_data_size
& 3) &&
944 fix_problem(ctx
, PR_2_BAD_INLINE_DIR_SIZE
, &pctx
)) {
945 errcode_t err
= fix_inline_dir_size(ctx
, ino
,
946 &inline_data_size
, &pctx
,
952 ehandler_operation(0);
953 if (cd
->pctx
.errcode
== EXT2_ET_DIR_CORRUPTED
)
954 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
955 else if (cd
->pctx
.errcode
== EXT2_ET_DIR_CSUM_INVALID
) {
956 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
959 if (cd
->pctx
.errcode
) {
961 if (!fix_problem(ctx
, PR_2_READ_DIRBLOCK
, &cd
->pctx
)) {
962 ctx
->flags
|= E2F_FLAG_ABORT
;
965 ext2fs_new_dir_block(fs
, db
->blockcnt
== 0 ? ino
: 0,
966 EXT2_ROOT_INO
, &buf2
);
967 memcpy(buf
, buf2
, fs
->blocksize
);
968 ext2fs_free_mem(&buf2
);
971 dx_dir
= e2fsck_get_dx_dir_info(ctx
, ino
);
972 if (dx_dir
&& dx_dir
->numblocks
) {
973 if (db
->blockcnt
>= dx_dir
->numblocks
) {
975 if (fix_problem(ctx
, PR_2_UNEXPECTED_HTREE_BLOCK
,
977 clear_htree(ctx
, ino
);
978 dx_dir
->numblocks
= 0;
982 fatal_error(ctx
, _("Can not continue."));
984 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
985 dx_db
->type
= DX_DIRBLOCK_LEAF
;
986 dx_db
->phys
= block_nr
;
987 dx_db
->min_hash
= ~0;
990 dirent
= (struct ext2_dir_entry
*) buf
;
991 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
992 limit
= (struct ext2_dx_countlimit
*) (buf
+8);
993 if (db
->blockcnt
== 0) {
994 root
= (struct ext2_dx_root_info
*) (buf
+ 24);
995 dx_db
->type
= DX_DIRBLOCK_ROOT
;
996 dx_db
->flags
|= DX_FLAG_FIRST
| DX_FLAG_LAST
;
997 if ((root
->reserved_zero
||
998 root
->info_length
< 8 ||
999 root
->indirect_levels
> 1) &&
1000 fix_problem(ctx
, PR_2_HTREE_BAD_ROOT
, &cd
->pctx
)) {
1001 clear_htree(ctx
, ino
);
1002 dx_dir
->numblocks
= 0;
1005 dx_dir
->hashversion
= root
->hash_version
;
1006 if ((dx_dir
->hashversion
<= EXT2_HASH_TEA
) &&
1007 (fs
->super
->s_flags
& EXT2_FLAGS_UNSIGNED_HASH
))
1008 dx_dir
->hashversion
+= 3;
1009 dx_dir
->depth
= root
->indirect_levels
+ 1;
1010 } else if ((dirent
->inode
== 0) &&
1011 (rec_len
== fs
->blocksize
) &&
1012 (ext2fs_dirent_name_len(dirent
) == 0) &&
1013 (ext2fs_le16_to_cpu(limit
->limit
) ==
1014 ((fs
->blocksize
- (8 + dx_csum_size
)) /
1015 sizeof(struct ext2_dx_entry
))))
1016 dx_db
->type
= DX_DIRBLOCK_NODE
;
1020 #endif /* ENABLE_HTREE */
1022 /* Leaf node with no space for csum? Rebuild dirs in pass 3A. */
1023 if (is_leaf
&& !inline_data_size
&& failed_csum
&&
1024 !ext2fs_dirent_has_tail(fs
, (struct ext2_dir_entry
*)buf
)) {
1026 if (e2fsck_dir_will_be_rehashed(ctx
, ino
)) {
1030 if (!fix_problem(cd
->ctx
, PR_2_LEAF_NODE_MISSING_CSUM
,
1033 e2fsck_rehash_dir_later(ctx
, ino
);
1037 /* htree nodes don't use fake dirents to store checksums */
1042 dict_init(&de_dict
, DICTCOUNT_T_MAX
, dict_de_cmp
);
1046 ext2_ino_t first_unused_inode
;
1047 unsigned int name_len
;
1050 if (!inline_data_size
|| dot_state
> 1) {
1051 size_t max_block_size
= fs
->blocksize
- de_csum_size
;
1053 if (inline_data_size
)
1054 max_block_size
= inline_data_size
;
1055 dirent
= (struct ext2_dir_entry
*) (buf
+ offset
);
1056 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
1057 cd
->pctx
.dirent
= dirent
;
1058 cd
->pctx
.num
= offset
;
1059 if (((offset
+ rec_len
) > fs
->blocksize
) ||
1060 (inline_data_size
> 0 &&
1061 (offset
+ rec_len
) > inline_data_size
) ||
1063 ((rec_len
% 4) != 0) ||
1064 ((ext2fs_dirent_name_len(dirent
) + 8) > rec_len
)) {
1065 if (fix_problem(ctx
, PR_2_DIR_CORRUPTED
,
1067 #ifdef WORDS_BIGENDIAN
1069 * On big-endian systems, if the dirent
1070 * swap routine finds a rec_len that it
1071 * doesn't like, it continues
1072 * processing the block as if rec_len
1073 * == 8. This means that the name
1074 * field gets byte swapped, which means
1075 * that salvage will not detect the
1076 * correct name length (unless the name
1077 * has a length that's an exact
1078 * multiple of four bytes), and it'll
1079 * discard the entry (unnecessarily)
1080 * and the rest of the dirent block.
1081 * Therefore, swap the rest of the
1082 * block back to disk order, run
1083 * salvage, and re-swap anything after
1084 * the salvaged dirent.
1086 int need_reswab
= 0;
1087 if (rec_len
< 8 || rec_len
% 4) {
1089 ext2fs_dirent_swab_in2(fs
,
1090 ((char *)dirent
) + 8,
1091 max_block_size
- offset
- 8,
1095 salvage_directory(fs
, dirent
, prev
,
1098 #ifdef WORDS_BIGENDIAN
1100 (void) ext2fs_get_rec_len(fs
,
1102 ext2fs_dirent_swab_in2(fs
,
1103 ((char *)dirent
) + offset
+ rec_len
,
1104 max_block_size
- offset
- rec_len
,
1111 goto abort_free_dict
;
1114 if (dot_state
== 0) {
1115 memset(&dot
, 0, sizeof(dot
));
1117 dirent
->inode
= ino
;
1118 dirent
->rec_len
= EXT2_DIR_REC_LEN(1);
1119 dirent
->name_len
= 1 | filetype
;
1120 dirent
->name
[0] = '.';
1121 } else if (dot_state
== 1) {
1122 memset(&dotdot
, 0, sizeof(dotdot
));
1125 ((struct ext2_dir_entry
*)buf
)->inode
;
1126 dirent
->rec_len
= EXT2_DIR_REC_LEN(2);
1127 dirent
->name_len
= 2 | filetype
;
1128 dirent
->name
[0] = '.';
1129 dirent
->name
[1] = '.';
1131 fatal_error(ctx
, _("Can not continue."));
1133 cd
->pctx
.dirent
= dirent
;
1134 cd
->pctx
.num
= offset
;
1137 if (dot_state
== 0) {
1138 if (check_dot(ctx
, dirent
, ino
, &cd
->pctx
))
1140 } else if (dot_state
== 1) {
1141 ret
= check_dotdot(ctx
, dirent
, ino
, &cd
->pctx
);
1143 goto abort_free_dict
;
1146 } else if (dirent
->inode
== ino
) {
1147 problem
= PR_2_LINK_DOT
;
1148 if (fix_problem(ctx
, PR_2_LINK_DOT
, &cd
->pctx
)) {
1158 * Make sure the inode listed is a legal one.
1160 name_len
= ext2fs_dirent_name_len(dirent
);
1161 if (((dirent
->inode
!= EXT2_ROOT_INO
) &&
1162 (dirent
->inode
< EXT2_FIRST_INODE(fs
->super
))) ||
1163 (dirent
->inode
> fs
->super
->s_inodes_count
)) {
1164 problem
= PR_2_BAD_INO
;
1165 } else if (ctx
->inode_bb_map
&&
1166 (ext2fs_test_inode_bitmap2(ctx
->inode_bb_map
,
1169 * If the inode is in a bad block, offer to
1172 problem
= PR_2_BB_INODE
;
1173 } else if ((dot_state
> 1) && (name_len
== 1) &&
1174 (dirent
->name
[0] == '.')) {
1176 * If there's a '.' entry in anything other
1177 * than the first directory entry, it's a
1178 * duplicate entry that should be removed.
1180 problem
= PR_2_DUP_DOT
;
1181 } else if ((dot_state
> 1) && (name_len
== 2) &&
1182 (dirent
->name
[0] == '.') &&
1183 (dirent
->name
[1] == '.')) {
1185 * If there's a '..' entry in anything other
1186 * than the second directory entry, it's a
1187 * duplicate entry that should be removed.
1189 problem
= PR_2_DUP_DOT_DOT
;
1190 } else if ((dot_state
> 1) &&
1191 (dirent
->inode
== EXT2_ROOT_INO
)) {
1193 * Don't allow links to the root directory.
1194 * We check this specially to make sure we
1195 * catch this error case even if the root
1196 * directory hasn't been created yet.
1198 problem
= PR_2_LINK_ROOT
;
1199 } else if ((dot_state
> 1) && (name_len
== 0)) {
1201 * Don't allow zero-length directory names.
1203 problem
= PR_2_NULL_NAME
;
1207 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
1212 ext2fs_unmark_valid(fs
);
1213 if (problem
== PR_2_BAD_INO
)
1219 * If the inode was marked as having bad fields in
1220 * pass1, process it and offer to fix/clear it.
1221 * (We wait until now so that we can display the
1222 * pathname to the user.)
1224 if (ctx
->inode_bad_map
&&
1225 ext2fs_test_inode_bitmap2(ctx
->inode_bad_map
,
1227 if (e2fsck_process_bad_inode(ctx
, ino
,
1229 buf
+ fs
->blocksize
)) {
1234 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
1235 return DIRENT_ABORT
;
1238 group
= ext2fs_group_of_ino(fs
, dirent
->inode
);
1239 first_unused_inode
= group
* fs
->super
->s_inodes_per_group
+
1240 1 + fs
->super
->s_inodes_per_group
-
1241 ext2fs_bg_itable_unused(fs
, group
);
1242 cd
->pctx
.group
= group
;
1245 * Check if the inode was missed out because
1246 * _INODE_UNINIT flag was set or bg_itable_unused was
1247 * incorrect. If so, clear the _INODE_UNINIT flag and
1248 * restart e2fsck. In the future it would be nice if
1249 * we could call a function in pass1.c that checks the
1250 * newly visible inodes.
1252 if (ext2fs_bg_flags_test(fs
, group
, EXT2_BG_INODE_UNINIT
)) {
1253 pctx
.num
= dirent
->inode
;
1254 if (fix_problem(ctx
, PR_2_INOREF_BG_INO_UNINIT
,
1256 ext2fs_bg_flags_clear(fs
, group
,
1257 EXT2_BG_INODE_UNINIT
);
1258 ext2fs_mark_super_dirty(fs
);
1259 ctx
->flags
|= E2F_FLAG_RESTART_LATER
;
1261 ext2fs_unmark_valid(fs
);
1262 if (problem
== PR_2_BAD_INO
)
1265 } else if (dirent
->inode
>= first_unused_inode
) {
1266 pctx
.num
= dirent
->inode
;
1267 if (fix_problem(ctx
, PR_2_INOREF_IN_UNUSED
, &cd
->pctx
)){
1268 ext2fs_bg_itable_unused_set(fs
, group
, 0);
1269 ext2fs_mark_super_dirty(fs
);
1270 ctx
->flags
|= E2F_FLAG_RESTART_LATER
;
1272 ext2fs_unmark_valid(fs
);
1273 if (problem
== PR_2_BAD_INO
)
1279 * Offer to clear unused inodes; if we are going to be
1280 * restarting the scan due to bg_itable_unused being
1281 * wrong, then don't clear any inodes to avoid zapping
1282 * inodes that were skipped during pass1 due to an
1283 * incorrect bg_itable_unused; we'll get any real
1284 * problems after we restart.
1286 if (!(ctx
->flags
& E2F_FLAG_RESTART_LATER
) &&
1287 !(ext2fs_test_inode_bitmap2(ctx
->inode_used_map
,
1289 problem
= PR_2_UNUSED_INODE
;
1292 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
1297 ext2fs_unmark_valid(fs
);
1298 if (problem
== PR_2_BAD_INO
)
1303 if (check_name(ctx
, dirent
, ino
, &cd
->pctx
))
1306 if (check_filetype(ctx
, dirent
, ino
, &cd
->pctx
))
1311 ext2fs_dirhash(dx_dir
->hashversion
, dirent
->name
,
1312 ext2fs_dirent_name_len(dirent
),
1313 fs
->super
->s_hash_seed
, &hash
, 0);
1314 if (hash
< dx_db
->min_hash
)
1315 dx_db
->min_hash
= hash
;
1316 if (hash
> dx_db
->max_hash
)
1317 dx_db
->max_hash
= hash
;
1322 * If this is a directory, then mark its parent in its
1323 * dir_info structure. If the parent field is already
1324 * filled in, then this directory has more than one
1325 * hard link. We assume the first link is correct,
1326 * and ask the user if he/she wants to clear this one.
1328 if ((dot_state
> 1) &&
1329 (ext2fs_test_inode_bitmap2(ctx
->inode_dir_map
,
1331 if (e2fsck_dir_info_get_parent(ctx
, dirent
->inode
,
1333 cd
->pctx
.ino
= dirent
->inode
;
1334 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
1335 goto abort_free_dict
;
1337 if (subdir_parent
) {
1338 cd
->pctx
.ino2
= subdir_parent
;
1339 if (fix_problem(ctx
, PR_2_LINK_DIR
,
1347 (void) e2fsck_dir_info_set_parent(ctx
,
1348 dirent
->inode
, ino
);
1354 } else if (dict_lookup(&de_dict
, dirent
)) {
1355 clear_problem_context(&pctx
);
1357 pctx
.dirent
= dirent
;
1358 fix_problem(ctx
, PR_2_REPORT_DUP_DIRENT
, &pctx
);
1359 e2fsck_rehash_dir_later(ctx
, ino
);
1362 dict_alloc_insert(&de_dict
, dirent
, dirent
);
1364 ext2fs_icount_increment(ctx
->inode_count
, dirent
->inode
,
1367 ctx
->fs_links_count
++;
1368 ctx
->fs_total_count
++;
1372 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
1373 if (!inline_data_size
|| dot_state
> 1) {
1376 if (dot_state
== 1) {
1379 * If we get here, we're checking an inline
1380 * directory and we've just checked a (fake)
1381 * dotdot entry that we created on the stack.
1382 * Therefore set 'prev' to NULL so that if we
1383 * call salvage_directory on the next entry,
1384 * it won't try to absorb the next entry into
1385 * the on-stack dotdot entry.
1391 } while (is_last_entry(fs
, inline_data_size
, offset
, de_csum_size
));
1398 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
1399 db
->blockcnt
, dx_db
->type
,
1400 dx_db
->min_hash
, dx_db
->max_hash
);
1402 cd
->pctx
.dir
= cd
->pctx
.ino
;
1403 if ((dx_db
->type
== DX_DIRBLOCK_ROOT
) ||
1404 (dx_db
->type
== DX_DIRBLOCK_NODE
))
1405 parse_int_node(fs
, db
, cd
, dx_dir
, buf
, failed_csum
);
1407 #endif /* ENABLE_HTREE */
1409 if (inline_data_size
) {
1410 if (offset
!= inline_data_size
) {
1411 cd
->pctx
.num
= rec_len
+ offset
- inline_data_size
;
1412 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
1413 dirent
->rec_len
= cd
->pctx
.num
;
1418 if (offset
!= fs
->blocksize
- de_csum_size
) {
1419 cd
->pctx
.num
= rec_len
- (fs
->blocksize
- de_csum_size
) +
1421 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
1422 dirent
->rec_len
= cd
->pctx
.num
;
1428 int flags
, will_rehash
;
1429 /* leaf block with no tail? Rehash dirs later. */
1430 if (EXT2_HAS_RO_COMPAT_FEATURE(fs
->super
,
1431 EXT4_FEATURE_RO_COMPAT_METADATA_CSUM
) &&
1433 !inline_data_size
&&
1434 !ext2fs_dirent_has_tail(fs
, (struct ext2_dir_entry
*)buf
)) {
1435 if (insert_dirent_tail(fs
, buf
) == 0)
1437 e2fsck_rehash_dir_later(ctx
, ino
);
1441 will_rehash
= e2fsck_dir_will_be_rehashed(ctx
, ino
);
1443 flags
= ctx
->fs
->flags
;
1444 ctx
->fs
->flags
|= EXT2_FLAG_IGNORE_CSUM_ERRORS
;
1446 if (inline_data_size
) {
1447 #ifdef WORDS_BIGENDIAN
1448 *((__u32
*)buf
) = ext2fs_le32_to_cpu(*((__u32
*)buf
));
1449 cd
->pctx
.errcode
= ext2fs_dirent_swab_out2(fs
,
1450 buf
+ EXT4_INLINE_DATA_DOTDOT_SIZE
,
1452 EXT4_INLINE_DATA_DOTDOT_SIZE
,
1454 if (cd
->pctx
.errcode
&&
1455 !fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
, &cd
->pctx
))
1456 goto abort_free_dict
;
1459 ext2fs_inline_data_set(fs
, ino
, 0, buf
,
1462 cd
->pctx
.errcode
= ext2fs_write_dir_block4(fs
, block_nr
,
1465 ctx
->fs
->flags
= (flags
&
1466 EXT2_FLAG_IGNORE_CSUM_ERRORS
) |
1468 ~EXT2_FLAG_IGNORE_CSUM_ERRORS
);
1469 if (cd
->pctx
.errcode
) {
1470 if (!fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
,
1472 goto abort_free_dict
;
1474 ext2fs_mark_changed(fs
);
1475 } else if (is_leaf
&& failed_csum
&& !dir_modified
) {
1477 * If a leaf node that fails csum makes it this far without
1478 * alteration, ask the user if the checksum should be fixed.
1480 if (fix_problem(ctx
, PR_2_LEAF_NODE_ONLY_CSUM_INVALID
,
1484 dict_free_nodes(&de_dict
);
1487 ctx
->flags
|= E2F_FLAG_ABORT
;
1488 dict_free_nodes(&de_dict
);
1489 return DIRENT_ABORT
;
1498 * This function is called to deallocate a block, and is an interator
1499 * functioned called by deallocate inode via ext2fs_iterate_block().
1501 static int deallocate_inode_block(ext2_filsys fs
,
1503 e2_blkcnt_t blockcnt
EXT2FS_ATTR((unused
)),
1504 blk64_t ref_block
EXT2FS_ATTR((unused
)),
1505 int ref_offset
EXT2FS_ATTR((unused
)),
1508 struct del_block
*p
= priv_data
;
1510 if (HOLE_BLKADDR(*block_nr
))
1512 if ((*block_nr
< fs
->super
->s_first_data_block
) ||
1513 (*block_nr
>= ext2fs_blocks_count(fs
->super
)))
1515 if ((*block_nr
% EXT2FS_CLUSTER_RATIO(fs
)) == 0)
1516 ext2fs_block_alloc_stats2(fs
, *block_nr
, -1);
1522 * This fuction deallocates an inode
1524 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
)
1526 ext2_filsys fs
= ctx
->fs
;
1527 struct ext2_inode inode
;
1528 struct problem_context pctx
;
1530 struct del_block del_block
;
1532 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
1533 clear_problem_context(&pctx
);
1537 * Fix up the bitmaps...
1539 e2fsck_read_bitmaps(ctx
);
1540 ext2fs_inode_alloc_stats2(fs
, ino
, -1, LINUX_S_ISDIR(inode
.i_mode
));
1542 if (ext2fs_file_acl_block(fs
, &inode
) &&
1543 (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
1544 pctx
.errcode
= ext2fs_adjust_ea_refcount3(fs
,
1545 ext2fs_file_acl_block(fs
, &inode
),
1546 block_buf
, -1, &count
, ino
);
1547 if (pctx
.errcode
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
1552 pctx
.blk
= ext2fs_file_acl_block(fs
, &inode
);
1553 fix_problem(ctx
, PR_2_ADJ_EA_REFCOUNT
, &pctx
);
1554 ctx
->flags
|= E2F_FLAG_ABORT
;
1558 ext2fs_block_alloc_stats2(fs
,
1559 ext2fs_file_acl_block(fs
, &inode
), -1);
1561 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1564 if (!ext2fs_inode_has_valid_blocks2(fs
, &inode
))
1567 /* Inline data inodes don't have blocks to iterate */
1568 if (inode
.i_flags
& EXT4_INLINE_DATA_FL
)
1571 if (LINUX_S_ISREG(inode
.i_mode
) &&
1572 ext2fs_needs_large_file_feature(EXT2_I_SIZE(&inode
)))
1575 del_block
.ctx
= ctx
;
1577 pctx
.errcode
= ext2fs_block_iterate3(fs
, ino
, 0, block_buf
,
1578 deallocate_inode_block
,
1581 fix_problem(ctx
, PR_2_DEALLOC_INODE
, &pctx
);
1582 ctx
->flags
|= E2F_FLAG_ABORT
;
1586 /* Inode may have changed by block_iterate, so reread it */
1587 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
1588 e2fsck_clear_inode(ctx
, ino
, &inode
, 0, "deallocate_inode");
1592 * This fuction clears the htree flag on an inode
1594 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
)
1596 struct ext2_inode inode
;
1598 e2fsck_read_inode(ctx
, ino
, &inode
, "clear_htree");
1599 inode
.i_flags
= inode
.i_flags
& ~EXT2_INDEX_FL
;
1600 e2fsck_write_inode(ctx
, ino
, &inode
, "clear_htree");
1601 if (ctx
->dirs_to_hash
)
1602 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
1606 int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
1607 ext2_ino_t ino
, char *buf
)
1609 ext2_filsys fs
= ctx
->fs
;
1610 struct ext2_inode inode
;
1611 int inode_modified
= 0;
1613 unsigned char *frag
, *fsize
;
1614 struct problem_context pctx
;
1615 problem_t problem
= 0;
1617 e2fsck_read_inode(ctx
, ino
, &inode
, "process_bad_inode");
1619 clear_problem_context(&pctx
);
1622 pctx
.inode
= &inode
;
1624 if (ext2fs_file_acl_block(fs
, &inode
) &&
1625 !(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
1626 if (fix_problem(ctx
, PR_2_FILE_ACL_ZERO
, &pctx
)) {
1627 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1633 if (!LINUX_S_ISDIR(inode
.i_mode
) && !LINUX_S_ISREG(inode
.i_mode
) &&
1634 !LINUX_S_ISCHR(inode
.i_mode
) && !LINUX_S_ISBLK(inode
.i_mode
) &&
1635 !LINUX_S_ISLNK(inode
.i_mode
) && !LINUX_S_ISFIFO(inode
.i_mode
) &&
1636 !(LINUX_S_ISSOCK(inode
.i_mode
)))
1637 problem
= PR_2_BAD_MODE
;
1638 else if (LINUX_S_ISCHR(inode
.i_mode
)
1639 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1640 problem
= PR_2_BAD_CHAR_DEV
;
1641 else if (LINUX_S_ISBLK(inode
.i_mode
)
1642 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1643 problem
= PR_2_BAD_BLOCK_DEV
;
1644 else if (LINUX_S_ISFIFO(inode
.i_mode
)
1645 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1646 problem
= PR_2_BAD_FIFO
;
1647 else if (LINUX_S_ISSOCK(inode
.i_mode
)
1648 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1649 problem
= PR_2_BAD_SOCKET
;
1650 else if (LINUX_S_ISLNK(inode
.i_mode
)
1651 && !e2fsck_pass1_check_symlink(fs
, ino
, &inode
, buf
)) {
1652 problem
= PR_2_INVALID_SYMLINK
;
1656 if (fix_problem(ctx
, problem
, &pctx
)) {
1657 deallocate_inode(ctx
, ino
, 0);
1658 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
1666 if (inode
.i_faddr
) {
1667 if (fix_problem(ctx
, PR_2_FADDR_ZERO
, &pctx
)) {
1674 switch (fs
->super
->s_creator_os
) {
1676 frag
= &inode
.osd2
.hurd2
.h_i_frag
;
1677 fsize
= &inode
.osd2
.hurd2
.h_i_fsize
;
1682 if (frag
&& *frag
) {
1684 if (fix_problem(ctx
, PR_2_FRAG_ZERO
, &pctx
)) {
1691 if (fsize
&& *fsize
) {
1693 if (fix_problem(ctx
, PR_2_FSIZE_ZERO
, &pctx
)) {
1701 if ((fs
->super
->s_creator_os
== EXT2_OS_LINUX
) &&
1702 !(fs
->super
->s_feature_ro_compat
&
1703 EXT4_FEATURE_RO_COMPAT_HUGE_FILE
) &&
1704 (inode
.osd2
.linux2
.l_i_blocks_hi
!= 0)) {
1705 pctx
.num
= inode
.osd2
.linux2
.l_i_blocks_hi
;
1706 if (fix_problem(ctx
, PR_2_BLOCKS_HI_ZERO
, &pctx
)) {
1707 inode
.osd2
.linux2
.l_i_blocks_hi
= 0;
1712 if (!(fs
->super
->s_feature_incompat
&
1713 EXT4_FEATURE_INCOMPAT_64BIT
) &&
1714 inode
.osd2
.linux2
.l_i_file_acl_high
!= 0) {
1715 pctx
.num
= inode
.osd2
.linux2
.l_i_file_acl_high
;
1716 if (fix_problem(ctx
, PR_2_I_FILE_ACL_HI_ZERO
, &pctx
)) {
1717 inode
.osd2
.linux2
.l_i_file_acl_high
= 0;
1723 if (ext2fs_file_acl_block(fs
, &inode
) &&
1724 ((ext2fs_file_acl_block(fs
, &inode
) < fs
->super
->s_first_data_block
) ||
1725 (ext2fs_file_acl_block(fs
, &inode
) >= ext2fs_blocks_count(fs
->super
)))) {
1726 if (fix_problem(ctx
, PR_2_FILE_ACL_BAD
, &pctx
)) {
1727 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1732 if (inode
.i_dir_acl
&&
1733 LINUX_S_ISDIR(inode
.i_mode
)) {
1734 if (fix_problem(ctx
, PR_2_DIR_ACL_ZERO
, &pctx
)) {
1735 inode
.i_dir_acl
= 0;
1742 e2fsck_write_inode(ctx
, ino
, &inode
, "process_bad_inode");
1743 if (!not_fixed
&& ctx
->inode_bad_map
)
1744 ext2fs_unmark_inode_bitmap2(ctx
->inode_bad_map
, ino
);
1749 * allocate_dir_block --- this function allocates a new directory
1750 * block for a particular inode; this is done if a directory has
1751 * a "hole" in it, or if a directory has a illegal block number
1752 * that was zeroed out and now needs to be replaced.
1754 static int allocate_dir_block(e2fsck_t ctx
,
1755 struct ext2_db_entry2
*db
,
1756 char *buf
EXT2FS_ATTR((unused
)),
1757 struct problem_context
*pctx
)
1759 ext2_filsys fs
= ctx
->fs
;
1762 struct ext2_inode inode
;
1764 if (fix_problem(ctx
, PR_2_DIRECTORY_HOLE
, pctx
) == 0)
1768 * Read the inode and block bitmaps in; we'll be messing with
1771 e2fsck_read_bitmaps(ctx
);
1774 * First, find a free block
1776 e2fsck_read_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1777 pctx
->errcode
= ext2fs_map_cluster_block(fs
, db
->ino
, &inode
,
1778 db
->blockcnt
, &blk
);
1779 if (pctx
->errcode
|| blk
== 0) {
1780 blk
= ext2fs_find_inode_goal(fs
, db
->ino
, &inode
, db
->blockcnt
);
1781 pctx
->errcode
= ext2fs_new_block2(fs
, blk
,
1782 ctx
->block_found_map
, &blk
);
1783 if (pctx
->errcode
) {
1784 pctx
->str
= "ext2fs_new_block";
1785 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1789 ext2fs_mark_block_bitmap2(ctx
->block_found_map
, blk
);
1790 ext2fs_mark_block_bitmap2(fs
->block_map
, blk
);
1791 ext2fs_mark_bb_dirty(fs
);
1794 * Now let's create the actual data block for the inode
1797 pctx
->errcode
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
1799 pctx
->errcode
= ext2fs_new_dir_block(fs
, db
->ino
,
1800 EXT2_ROOT_INO
, &block
);
1802 if (pctx
->errcode
) {
1803 pctx
->str
= "ext2fs_new_dir_block";
1804 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1808 pctx
->errcode
= ext2fs_write_dir_block4(fs
, blk
, block
, 0, db
->ino
);
1809 ext2fs_free_mem(&block
);
1810 if (pctx
->errcode
) {
1811 pctx
->str
= "ext2fs_write_dir_block";
1812 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1817 * Update the inode block count
1819 ext2fs_iblk_add_blocks(fs
, &inode
, 1);
1820 if (EXT2_I_SIZE(&inode
) < (db
->blockcnt
+1) * fs
->blocksize
) {
1821 pctx
->errcode
= ext2fs_inode_size_set(fs
, &inode
,
1822 (db
->blockcnt
+1) * fs
->blocksize
);
1823 if (pctx
->errcode
) {
1824 pctx
->str
= "ext2fs_inode_size_set";
1825 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1829 e2fsck_write_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1832 * Finally, update the block pointers for the inode
1835 pctx
->errcode
= ext2fs_bmap2(fs
, db
->ino
, &inode
, 0, BMAP_SET
,
1836 db
->blockcnt
, 0, &blk
);
1837 if (pctx
->errcode
) {
1838 pctx
->str
= "ext2fs_block_iterate";
1839 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);