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 (dx_dir
->numblocks
== 0)
171 clear_problem_context(&pctx
);
173 pctx
.dir
= dx_dir
->ino
;
174 dx_db
= dx_dir
->dx_block
;
175 if (dx_db
->flags
& DX_FLAG_REFERENCED
)
176 dx_db
->flags
|= DX_FLAG_DUP_REF
;
178 dx_db
->flags
|= DX_FLAG_REFERENCED
;
180 * Find all of the first and last leaf blocks, and
181 * update their parent's min and max hash values
183 for (b
=0, dx_db
= dx_dir
->dx_block
;
184 b
< dx_dir
->numblocks
;
186 if ((dx_db
->type
!= DX_DIRBLOCK_LEAF
) ||
187 !(dx_db
->flags
& (DX_FLAG_FIRST
| DX_FLAG_LAST
)))
189 dx_parent
= &dx_dir
->dx_block
[dx_db
->parent
];
191 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
193 if (dx_db
->flags
& DX_FLAG_FIRST
)
194 dx_parent
->min_hash
= dx_db
->min_hash
;
196 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
198 if (dx_db
->flags
& DX_FLAG_LAST
)
199 dx_parent
->max_hash
= dx_db
->max_hash
;
202 for (b
=0, dx_db
= dx_dir
->dx_block
;
203 b
< dx_dir
->numblocks
;
206 pctx
.group
= dx_db
->parent
;
208 if (!(dx_db
->flags
& DX_FLAG_FIRST
) &&
209 (dx_db
->min_hash
< dx_db
->node_min_hash
)) {
210 pctx
.blk
= dx_db
->min_hash
;
211 pctx
.blk2
= dx_db
->node_min_hash
;
212 code
= PR_2_HTREE_MIN_HASH
;
213 fix_problem(ctx
, code
, &pctx
);
216 if (dx_db
->type
== DX_DIRBLOCK_LEAF
) {
217 depth
= htree_depth(dx_dir
, dx_db
);
218 if (depth
!= dx_dir
->depth
) {
219 pctx
.num
= dx_dir
->depth
;
220 code
= PR_2_HTREE_BAD_DEPTH
;
221 fix_problem(ctx
, code
, &pctx
);
226 * This test doesn't apply for the root block
230 (dx_db
->max_hash
> dx_db
->node_max_hash
)) {
231 pctx
.blk
= dx_db
->max_hash
;
232 pctx
.blk2
= dx_db
->node_max_hash
;
233 code
= PR_2_HTREE_MAX_HASH
;
234 fix_problem(ctx
, code
, &pctx
);
237 if (!(dx_db
->flags
& DX_FLAG_REFERENCED
)) {
238 code
= PR_2_HTREE_NOTREF
;
239 fix_problem(ctx
, code
, &pctx
);
241 } else if (dx_db
->flags
& DX_FLAG_DUP_REF
) {
242 code
= PR_2_HTREE_DUPREF
;
243 fix_problem(ctx
, code
, &pctx
);
247 if (bad_dir
&& fix_problem(ctx
, PR_2_HTREE_CLEAR
, &pctx
)) {
248 clear_htree(ctx
, dx_dir
->ino
);
249 dx_dir
->numblocks
= 0;
252 e2fsck_free_dx_dir_info(ctx
);
254 ext2fs_free_mem(&buf
);
255 ext2fs_free_dblist(fs
->dblist
);
257 if (ctx
->inode_bad_map
) {
258 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
259 ctx
->inode_bad_map
= 0;
261 if (ctx
->inode_reg_map
) {
262 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
263 ctx
->inode_reg_map
= 0;
266 clear_problem_context(&pctx
);
267 if (ctx
->large_files
) {
268 if (!(sb
->s_feature_ro_compat
&
269 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
) &&
270 fix_problem(ctx
, PR_2_FEATURE_LARGE_FILES
, &pctx
)) {
271 sb
->s_feature_ro_compat
|=
272 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
273 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
274 ext2fs_mark_super_dirty(fs
);
276 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
277 fix_problem(ctx
, PR_1_FS_REV_LEVEL
, &pctx
)) {
278 ext2fs_update_dynamic_rev(fs
);
279 ext2fs_mark_super_dirty(fs
);
283 print_resource_track(ctx
, _("Pass 2"), &rtrack
, fs
->io
);
286 #define MAX_DEPTH 32000
287 static int htree_depth(struct dx_dir_info
*dx_dir
,
288 struct dx_dirblock_info
*dx_db
)
292 while (dx_db
->type
!= DX_DIRBLOCK_ROOT
&& depth
< MAX_DEPTH
) {
293 dx_db
= &dx_dir
->dx_block
[dx_db
->parent
];
299 static int dict_de_cmp(const void *a
, const void *b
)
301 const struct ext2_dir_entry
*de_a
, *de_b
;
304 de_a
= (const struct ext2_dir_entry
*) a
;
305 a_len
= de_a
->name_len
& 0xFF;
306 de_b
= (const struct ext2_dir_entry
*) b
;
307 b_len
= de_b
->name_len
& 0xFF;
310 return (a_len
- b_len
);
312 return strncmp(de_a
->name
, de_b
->name
, a_len
);
316 * This is special sort function that makes sure that directory blocks
317 * with a dirblock of zero are sorted to the beginning of the list.
318 * This guarantees that the root node of the htree directories are
319 * processed first, so we know what hash version to use.
321 static EXT2_QSORT_TYPE
special_dir_block_cmp(const void *a
, const void *b
)
323 const struct ext2_db_entry2
*db_a
=
324 (const struct ext2_db_entry2
*) a
;
325 const struct ext2_db_entry2
*db_b
=
326 (const struct ext2_db_entry2
*) b
;
328 if (db_a
->blockcnt
&& !db_b
->blockcnt
)
331 if (!db_a
->blockcnt
&& db_b
->blockcnt
)
334 if (db_a
->blk
!= db_b
->blk
)
335 return (int) (db_a
->blk
- db_b
->blk
);
337 if (db_a
->ino
!= db_b
->ino
)
338 return (int) (db_a
->ino
- db_b
->ino
);
340 return (int) (db_a
->blockcnt
- db_b
->blockcnt
);
345 * Make sure the first entry in the directory is '.', and that the
346 * directory entry is sane.
348 static int check_dot(e2fsck_t ctx
,
349 struct ext2_dir_entry
*dirent
,
350 ext2_ino_t ino
, struct problem_context
*pctx
)
352 struct ext2_dir_entry
*nextdir
;
353 unsigned int rec_len
, new_len
;
356 problem_t problem
= 0;
359 problem
= PR_2_MISSING_DOT
;
360 else if (((dirent
->name_len
& 0xFF) != 1) ||
361 (dirent
->name
[0] != '.'))
362 problem
= PR_2_1ST_NOT_DOT
;
363 else if (dirent
->name
[1] != '\0')
364 problem
= PR_2_DOT_NULL_TERM
;
366 (void) ext2fs_get_rec_len(ctx
->fs
, dirent
, &rec_len
);
368 if (fix_problem(ctx
, problem
, pctx
)) {
370 rec_len
= dirent
->rec_len
= 12;
372 dirent
->name_len
= 1;
373 dirent
->name
[0] = '.';
374 dirent
->name
[1] = '\0';
379 if (dirent
->inode
!= ino
) {
380 if (fix_problem(ctx
, PR_2_BAD_INODE_DOT
, pctx
)) {
386 new_len
= rec_len
- 12;
389 fix_problem(ctx
, PR_2_SPLIT_DOT
, pctx
)) {
390 nextdir
= (struct ext2_dir_entry
*)
391 ((char *) dirent
+ 12);
392 dirent
->rec_len
= 12;
393 (void) ext2fs_set_rec_len(ctx
->fs
, new_len
,
396 nextdir
->name_len
= 0;
405 * Make sure the second entry in the directory is '..', and that the
406 * directory entry is sane. We do not check the inode number of '..'
407 * here; this gets done in pass 3.
409 static int check_dotdot(e2fsck_t ctx
,
410 struct ext2_dir_entry
*dirent
,
411 ext2_ino_t ino
, struct problem_context
*pctx
)
413 problem_t problem
= 0;
414 unsigned int rec_len
;
417 problem
= PR_2_MISSING_DOT_DOT
;
418 else if (((dirent
->name_len
& 0xFF) != 2) ||
419 (dirent
->name
[0] != '.') ||
420 (dirent
->name
[1] != '.'))
421 problem
= PR_2_2ND_NOT_DOT_DOT
;
422 else if (dirent
->name
[2] != '\0')
423 problem
= PR_2_DOT_DOT_NULL_TERM
;
425 (void) ext2fs_get_rec_len(ctx
->fs
, dirent
, &rec_len
);
427 if (fix_problem(ctx
, problem
, pctx
)) {
429 dirent
->rec_len
= 12;
431 * Note: we don't have the parent inode just
432 * yet, so we will fill it in with the root
433 * inode. This will get fixed in pass 3.
435 dirent
->inode
= EXT2_ROOT_INO
;
436 dirent
->name_len
= 2;
437 dirent
->name
[0] = '.';
438 dirent
->name
[1] = '.';
439 dirent
->name
[2] = '\0';
444 if (e2fsck_dir_info_set_dotdot(ctx
, ino
, dirent
->inode
)) {
445 fix_problem(ctx
, PR_2_NO_DIRINFO
, pctx
);
452 * Check to make sure a directory entry doesn't contain any illegal
455 static int check_name(e2fsck_t ctx
,
456 struct ext2_dir_entry
*dirent
,
457 ext2_ino_t dir_ino
EXT2FS_ATTR((unused
)),
458 struct problem_context
*pctx
)
464 for ( i
= 0; i
< (dirent
->name_len
& 0xFF); i
++) {
465 if (dirent
->name
[i
] == '/' || dirent
->name
[i
] == '\0') {
467 fixup
= fix_problem(ctx
, PR_2_BAD_NAME
, pctx
);
470 dirent
->name
[i
] = '.';
479 * Check the directory filetype (if present)
481 static _INLINE_
int check_filetype(e2fsck_t ctx
,
482 struct ext2_dir_entry
*dirent
,
483 ext2_ino_t dir_ino
EXT2FS_ATTR((unused
)),
484 struct problem_context
*pctx
)
486 int filetype
= dirent
->name_len
>> 8;
487 int should_be
= EXT2_FT_UNKNOWN
;
488 struct ext2_inode inode
;
490 if (!(ctx
->fs
->super
->s_feature_incompat
&
491 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
493 !fix_problem(ctx
, PR_2_CLEAR_FILETYPE
, pctx
))
495 dirent
->name_len
= dirent
->name_len
& 0xFF;
499 if (ext2fs_test_inode_bitmap2(ctx
->inode_dir_map
, dirent
->inode
)) {
500 should_be
= EXT2_FT_DIR
;
501 } else if (ext2fs_test_inode_bitmap2(ctx
->inode_reg_map
,
503 should_be
= EXT2_FT_REG_FILE
;
504 } else if (ctx
->inode_bad_map
&&
505 ext2fs_test_inode_bitmap2(ctx
->inode_bad_map
,
509 e2fsck_read_inode(ctx
, dirent
->inode
, &inode
,
511 should_be
= ext2_file_type(inode
.i_mode
);
513 if (filetype
== should_be
)
515 pctx
->num
= should_be
;
517 if (fix_problem(ctx
, filetype
? PR_2_BAD_FILETYPE
: PR_2_SET_FILETYPE
,
521 dirent
->name_len
= (dirent
->name_len
& 0xFF) | should_be
<< 8;
526 static void parse_int_node(ext2_filsys fs
,
527 struct ext2_db_entry2
*db
,
528 struct check_dir_struct
*cd
,
529 struct dx_dir_info
*dx_dir
,
532 struct ext2_dx_root_info
*root
;
533 struct ext2_dx_entry
*ent
;
534 struct ext2_dx_countlimit
*limit
;
535 struct dx_dirblock_info
*dx_db
;
536 int i
, expect_limit
, count
;
538 ext2_dirhash_t min_hash
= 0xffffffff;
539 ext2_dirhash_t max_hash
= 0;
540 ext2_dirhash_t hash
= 0, prev_hash
;
542 if (db
->blockcnt
== 0) {
543 root
= (struct ext2_dx_root_info
*) (block_buf
+ 24);
546 printf("Root node dump:\n");
547 printf("\t Reserved zero: %u\n", root
->reserved_zero
);
548 printf("\t Hash Version: %d\n", root
->hash_version
);
549 printf("\t Info length: %d\n", root
->info_length
);
550 printf("\t Indirect levels: %d\n", root
->indirect_levels
);
551 printf("\t Flags: %d\n", root
->unused_flags
);
554 ent
= (struct ext2_dx_entry
*) (block_buf
+ 24 + root
->info_length
);
556 ent
= (struct ext2_dx_entry
*) (block_buf
+8);
558 limit
= (struct ext2_dx_countlimit
*) ent
;
561 printf("Number of entries (count): %d\n",
562 ext2fs_le16_to_cpu(limit
->count
));
563 printf("Number of entries (limit): %d\n",
564 ext2fs_le16_to_cpu(limit
->limit
));
567 count
= ext2fs_le16_to_cpu(limit
->count
);
568 expect_limit
= (fs
->blocksize
- ((char *) ent
- block_buf
)) /
569 sizeof(struct ext2_dx_entry
);
570 if (ext2fs_le16_to_cpu(limit
->limit
) != expect_limit
) {
571 cd
->pctx
.num
= ext2fs_le16_to_cpu(limit
->limit
);
572 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_LIMIT
, &cd
->pctx
))
575 if (count
> expect_limit
) {
576 cd
->pctx
.num
= count
;
577 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_COUNT
, &cd
->pctx
))
579 count
= expect_limit
;
582 for (i
=0; i
< count
; i
++) {
584 hash
= i
? (ext2fs_le32_to_cpu(ent
[i
].hash
) & ~1) : 0;
586 printf("Entry #%d: Hash 0x%08x, block %u\n", i
,
587 hash
, ext2fs_le32_to_cpu(ent
[i
].block
));
589 blk
= ext2fs_le32_to_cpu(ent
[i
].block
) & 0x0ffffff;
590 /* Check to make sure the block is valid */
591 if (blk
>= (blk_t
) dx_dir
->numblocks
) {
593 if (fix_problem(cd
->ctx
, PR_2_HTREE_BADBLK
,
598 if (hash
< prev_hash
&&
599 fix_problem(cd
->ctx
, PR_2_HTREE_HASH_ORDER
, &cd
->pctx
))
601 dx_db
= &dx_dir
->dx_block
[blk
];
602 if (dx_db
->flags
& DX_FLAG_REFERENCED
) {
603 dx_db
->flags
|= DX_FLAG_DUP_REF
;
605 dx_db
->flags
|= DX_FLAG_REFERENCED
;
606 dx_db
->parent
= db
->blockcnt
;
612 dx_db
->node_min_hash
= hash
;
614 dx_db
->node_max_hash
=
615 ext2fs_le32_to_cpu(ent
[i
+1].hash
) & ~1;
617 dx_db
->node_max_hash
= 0xfffffffe;
618 dx_db
->flags
|= DX_FLAG_LAST
;
621 dx_db
->flags
|= DX_FLAG_FIRST
;
624 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
625 db
->blockcnt
, min_hash
, max_hash
);
627 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
628 dx_db
->min_hash
= min_hash
;
629 dx_db
->max_hash
= max_hash
;
633 clear_htree(cd
->ctx
, cd
->pctx
.ino
);
634 dx_dir
->numblocks
= 0;
636 #endif /* ENABLE_HTREE */
639 * Given a busted directory, try to salvage it somehow.
642 static void salvage_directory(ext2_filsys fs
,
643 struct ext2_dir_entry
*dirent
,
644 struct ext2_dir_entry
*prev
,
645 unsigned int *offset
)
647 char *cp
= (char *) dirent
;
649 unsigned int rec_len
, prev_rec_len
;
650 unsigned int name_len
= dirent
->name_len
& 0xFF;
652 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
653 left
= fs
->blocksize
- *offset
- rec_len
;
656 * Special case of directory entry of size 8: copy what's left
657 * of the directory block up to cover up the invalid hole.
659 if ((left
>= 12) && (rec_len
== 8)) {
660 memmove(cp
, cp
+8, left
);
661 memset(cp
+ left
, 0, 8);
665 * If the directory entry overruns the end of the directory
666 * block, and the name is small enough to fit, then adjust the
670 ((int) rec_len
+ left
> 8) &&
671 ((int) name_len
+ 8 <= (int) rec_len
+ left
) &&
672 dirent
->inode
<= fs
->super
->s_inodes_count
&&
673 strnlen(dirent
->name
, name_len
) == name_len
) {
674 (void) ext2fs_set_rec_len(fs
, (int) rec_len
+ left
, dirent
);
678 * If the record length of the directory entry is a multiple
679 * of four, and not too big, such that it is valid, let the
680 * previous directory entry absorb the invalid one.
682 if (prev
&& rec_len
&& (rec_len
% 4) == 0 &&
683 (*offset
+ rec_len
<= fs
->blocksize
)) {
684 (void) ext2fs_get_rec_len(fs
, prev
, &prev_rec_len
);
685 prev_rec_len
+= rec_len
;
686 (void) ext2fs_set_rec_len(fs
, prev_rec_len
, prev
);
691 * Default salvage method --- kill all of the directory
692 * entries for the rest of the block. We will either try to
693 * absorb it into the previous directory entry, or create a
694 * new empty directory entry the rest of the directory block.
697 (void) ext2fs_get_rec_len(fs
, prev
, &prev_rec_len
);
698 prev_rec_len
+= fs
->blocksize
- *offset
;
699 (void) ext2fs_set_rec_len(fs
, prev_rec_len
, prev
);
700 *offset
= fs
->blocksize
;
702 rec_len
= fs
->blocksize
- *offset
;
703 (void) ext2fs_set_rec_len(fs
, rec_len
, dirent
);
704 dirent
->name_len
= 0;
709 static int check_dir_block(ext2_filsys fs
,
710 struct ext2_db_entry2
*db
,
713 struct dx_dir_info
*dx_dir
;
715 struct dx_dirblock_info
*dx_db
= 0;
716 #endif /* ENABLE_HTREE */
717 struct ext2_dir_entry
*dirent
, *prev
;
719 unsigned int offset
= 0;
720 int dir_modified
= 0;
722 unsigned int rec_len
;
723 blk64_t block_nr
= db
->blk
;
724 ext2_ino_t ino
= db
->ino
;
725 ext2_ino_t subdir_parent
;
727 struct check_dir_struct
*cd
;
731 struct ext2_dx_root_info
*root
;
732 struct ext2_dx_countlimit
*limit
;
733 static dict_t de_dict
;
734 struct problem_context pctx
;
738 cd
= (struct check_dir_struct
*) priv_data
;
742 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
|| ctx
->flags
& E2F_FLAG_RESTART
)
745 if (ctx
->progress
&& (ctx
->progress
)(ctx
, 2, cd
->count
++, cd
->max
))
749 * Make sure the inode is still in use (could have been
750 * deleted in the duplicate/bad blocks pass.
752 if (!(ext2fs_test_inode_bitmap2(ctx
->inode_used_map
, ino
)))
756 cd
->pctx
.blk
= block_nr
;
757 cd
->pctx
.blkcount
= db
->blockcnt
;
763 if (allocate_dir_block(ctx
, db
, buf
, &cd
->pctx
))
773 if (ctx
->dirs_to_hash
&&
774 ext2fs_u32_list_test(ctx
->dirs_to_hash
, ino
))
778 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr
,
782 ehandler_operation(_("reading directory block"));
783 cd
->pctx
.errcode
= ext2fs_read_dir_block3(fs
, block_nr
, buf
, 0);
784 ehandler_operation(0);
785 if (cd
->pctx
.errcode
== EXT2_ET_DIR_CORRUPTED
)
786 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
787 if (cd
->pctx
.errcode
) {
788 if (!fix_problem(ctx
, PR_2_READ_DIRBLOCK
, &cd
->pctx
)) {
789 ctx
->flags
|= E2F_FLAG_ABORT
;
792 memset(buf
, 0, fs
->blocksize
);
795 dx_dir
= e2fsck_get_dx_dir_info(ctx
, ino
);
796 if (dx_dir
&& dx_dir
->numblocks
) {
797 if (db
->blockcnt
>= dx_dir
->numblocks
) {
798 if (fix_problem(ctx
, PR_2_UNEXPECTED_HTREE_BLOCK
,
800 clear_htree(ctx
, ino
);
801 dx_dir
->numblocks
= 0;
805 fatal_error(ctx
, _("Can not continue."));
807 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
808 dx_db
->type
= DX_DIRBLOCK_LEAF
;
809 dx_db
->phys
= block_nr
;
810 dx_db
->min_hash
= ~0;
813 dirent
= (struct ext2_dir_entry
*) buf
;
814 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
815 limit
= (struct ext2_dx_countlimit
*) (buf
+8);
816 if (db
->blockcnt
== 0) {
817 root
= (struct ext2_dx_root_info
*) (buf
+ 24);
818 dx_db
->type
= DX_DIRBLOCK_ROOT
;
819 dx_db
->flags
|= DX_FLAG_FIRST
| DX_FLAG_LAST
;
820 if ((root
->reserved_zero
||
821 root
->info_length
< 8 ||
822 root
->indirect_levels
> 1) &&
823 fix_problem(ctx
, PR_2_HTREE_BAD_ROOT
, &cd
->pctx
)) {
824 clear_htree(ctx
, ino
);
825 dx_dir
->numblocks
= 0;
828 dx_dir
->hashversion
= root
->hash_version
;
829 if ((dx_dir
->hashversion
<= EXT2_HASH_TEA
) &&
830 (fs
->super
->s_flags
& EXT2_FLAGS_UNSIGNED_HASH
))
831 dx_dir
->hashversion
+= 3;
832 dx_dir
->depth
= root
->indirect_levels
+ 1;
833 } else if ((dirent
->inode
== 0) &&
834 (rec_len
== fs
->blocksize
) &&
835 (dirent
->name_len
== 0) &&
836 (ext2fs_le16_to_cpu(limit
->limit
) ==
838 sizeof(struct ext2_dx_entry
))))
839 dx_db
->type
= DX_DIRBLOCK_NODE
;
842 #endif /* ENABLE_HTREE */
844 dict_init(&de_dict
, DICTCOUNT_T_MAX
, dict_de_cmp
);
848 ext2_ino_t first_unused_inode
;
851 dirent
= (struct ext2_dir_entry
*) (buf
+ offset
);
852 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
853 cd
->pctx
.dirent
= dirent
;
854 cd
->pctx
.num
= offset
;
855 if (((offset
+ rec_len
) > fs
->blocksize
) ||
857 ((rec_len
% 4) != 0) ||
858 (((dirent
->name_len
& (unsigned) 0xFF)+8) > rec_len
)) {
859 if (fix_problem(ctx
, PR_2_DIR_CORRUPTED
, &cd
->pctx
)) {
860 salvage_directory(fs
, dirent
, prev
, &offset
);
864 goto abort_free_dict
;
867 if (dot_state
== 0) {
868 if (check_dot(ctx
, dirent
, ino
, &cd
->pctx
))
870 } else if (dot_state
== 1) {
871 ret
= check_dotdot(ctx
, dirent
, ino
, &cd
->pctx
);
873 goto abort_free_dict
;
876 } else if (dirent
->inode
== ino
) {
877 problem
= PR_2_LINK_DOT
;
878 if (fix_problem(ctx
, PR_2_LINK_DOT
, &cd
->pctx
)) {
888 * Make sure the inode listed is a legal one.
890 if (((dirent
->inode
!= EXT2_ROOT_INO
) &&
891 (dirent
->inode
< EXT2_FIRST_INODE(fs
->super
))) ||
892 (dirent
->inode
> fs
->super
->s_inodes_count
)) {
893 problem
= PR_2_BAD_INO
;
894 } else if (ctx
->inode_bb_map
&&
895 (ext2fs_test_inode_bitmap2(ctx
->inode_bb_map
,
898 * If the inode is in a bad block, offer to
901 problem
= PR_2_BB_INODE
;
902 } else if ((dot_state
> 1) &&
903 ((dirent
->name_len
& 0xFF) == 1) &&
904 (dirent
->name
[0] == '.')) {
906 * If there's a '.' entry in anything other
907 * than the first directory entry, it's a
908 * duplicate entry that should be removed.
910 problem
= PR_2_DUP_DOT
;
911 } else if ((dot_state
> 1) &&
912 ((dirent
->name_len
& 0xFF) == 2) &&
913 (dirent
->name
[0] == '.') &&
914 (dirent
->name
[1] == '.')) {
916 * If there's a '..' entry in anything other
917 * than the second directory entry, it's a
918 * duplicate entry that should be removed.
920 problem
= PR_2_DUP_DOT_DOT
;
921 } else if ((dot_state
> 1) &&
922 (dirent
->inode
== EXT2_ROOT_INO
)) {
924 * Don't allow links to the root directory.
925 * We check this specially to make sure we
926 * catch this error case even if the root
927 * directory hasn't been created yet.
929 problem
= PR_2_LINK_ROOT
;
930 } else if ((dot_state
> 1) &&
931 (dirent
->name_len
& 0xFF) == 0) {
933 * Don't allow zero-length directory names.
935 problem
= PR_2_NULL_NAME
;
939 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
944 ext2fs_unmark_valid(fs
);
945 if (problem
== PR_2_BAD_INO
)
951 * If the inode was marked as having bad fields in
952 * pass1, process it and offer to fix/clear it.
953 * (We wait until now so that we can display the
954 * pathname to the user.)
956 if (ctx
->inode_bad_map
&&
957 ext2fs_test_inode_bitmap2(ctx
->inode_bad_map
,
959 if (e2fsck_process_bad_inode(ctx
, ino
,
961 buf
+ fs
->blocksize
)) {
966 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
970 group
= ext2fs_group_of_ino(fs
, dirent
->inode
);
971 first_unused_inode
= group
* fs
->super
->s_inodes_per_group
+
972 1 + fs
->super
->s_inodes_per_group
-
973 ext2fs_bg_itable_unused(fs
, group
);
974 cd
->pctx
.group
= group
;
977 * Check if the inode was missed out because
978 * _INODE_UNINIT flag was set or bg_itable_unused was
979 * incorrect. If so, clear the _INODE_UNINIT flag and
980 * restart e2fsck. In the future it would be nice if
981 * we could call a function in pass1.c that checks the
982 * newly visible inodes.
984 if (ext2fs_bg_flags_test(fs
, group
, EXT2_BG_INODE_UNINIT
)) {
985 pctx
.num
= dirent
->inode
;
986 if (fix_problem(ctx
, PR_2_INOREF_BG_INO_UNINIT
,
988 ext2fs_bg_flags_clear(fs
, group
,
989 EXT2_BG_INODE_UNINIT
);
990 ext2fs_mark_super_dirty(fs
);
991 ctx
->flags
|= E2F_FLAG_RESTART_LATER
;
993 ext2fs_unmark_valid(fs
);
994 if (problem
== PR_2_BAD_INO
)
997 } else if (dirent
->inode
>= first_unused_inode
) {
998 pctx
.num
= dirent
->inode
;
999 if (fix_problem(ctx
, PR_2_INOREF_IN_UNUSED
, &cd
->pctx
)){
1000 ext2fs_bg_itable_unused_set(fs
, group
, 0);
1001 ext2fs_mark_super_dirty(fs
);
1002 ctx
->flags
|= E2F_FLAG_RESTART_LATER
;
1004 ext2fs_unmark_valid(fs
);
1005 if (problem
== PR_2_BAD_INO
)
1011 * Offer to clear unused inodes; if we are going to be
1012 * restarting the scan due to bg_itable_unused being
1013 * wrong, then don't clear any inodes to avoid zapping
1014 * inodes that were skipped during pass1 due to an
1015 * incorrect bg_itable_unused; we'll get any real
1016 * problems after we restart.
1018 if (!(ctx
->flags
& E2F_FLAG_RESTART_LATER
) &&
1019 !(ext2fs_test_inode_bitmap2(ctx
->inode_used_map
,
1021 problem
= PR_2_UNUSED_INODE
;
1024 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
1029 ext2fs_unmark_valid(fs
);
1030 if (problem
== PR_2_BAD_INO
)
1035 if (check_name(ctx
, dirent
, ino
, &cd
->pctx
))
1038 if (check_filetype(ctx
, dirent
, ino
, &cd
->pctx
))
1043 ext2fs_dirhash(dx_dir
->hashversion
, dirent
->name
,
1044 (dirent
->name_len
& 0xFF),
1045 fs
->super
->s_hash_seed
, &hash
, 0);
1046 if (hash
< dx_db
->min_hash
)
1047 dx_db
->min_hash
= hash
;
1048 if (hash
> dx_db
->max_hash
)
1049 dx_db
->max_hash
= hash
;
1054 * If this is a directory, then mark its parent in its
1055 * dir_info structure. If the parent field is already
1056 * filled in, then this directory has more than one
1057 * hard link. We assume the first link is correct,
1058 * and ask the user if he/she wants to clear this one.
1060 if ((dot_state
> 1) &&
1061 (ext2fs_test_inode_bitmap2(ctx
->inode_dir_map
,
1063 if (e2fsck_dir_info_get_parent(ctx
, dirent
->inode
,
1065 cd
->pctx
.ino
= dirent
->inode
;
1066 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
1067 goto abort_free_dict
;
1069 if (subdir_parent
) {
1070 cd
->pctx
.ino2
= subdir_parent
;
1071 if (fix_problem(ctx
, PR_2_LINK_DIR
,
1079 (void) e2fsck_dir_info_set_parent(ctx
,
1080 dirent
->inode
, ino
);
1086 } else if (dict_lookup(&de_dict
, dirent
)) {
1087 clear_problem_context(&pctx
);
1089 pctx
.dirent
= dirent
;
1090 fix_problem(ctx
, PR_2_REPORT_DUP_DIRENT
, &pctx
);
1091 if (!ctx
->dirs_to_hash
)
1092 ext2fs_u32_list_create(&ctx
->dirs_to_hash
, 50);
1093 if (ctx
->dirs_to_hash
)
1094 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
1097 dict_alloc_insert(&de_dict
, dirent
, dirent
);
1099 ext2fs_icount_increment(ctx
->inode_count
, dirent
->inode
,
1102 ctx
->fs_links_count
++;
1103 ctx
->fs_total_count
++;
1107 (void) ext2fs_get_rec_len(fs
, dirent
, &rec_len
);
1110 } while (offset
< fs
->blocksize
);
1117 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
1118 db
->blockcnt
, dx_db
->type
,
1119 dx_db
->min_hash
, dx_db
->max_hash
);
1121 cd
->pctx
.dir
= cd
->pctx
.ino
;
1122 if ((dx_db
->type
== DX_DIRBLOCK_ROOT
) ||
1123 (dx_db
->type
== DX_DIRBLOCK_NODE
))
1124 parse_int_node(fs
, db
, cd
, dx_dir
, buf
);
1126 #endif /* ENABLE_HTREE */
1127 if (offset
!= fs
->blocksize
) {
1128 cd
->pctx
.num
= rec_len
- fs
->blocksize
+ offset
;
1129 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
1130 dirent
->rec_len
= cd
->pctx
.num
;
1135 cd
->pctx
.errcode
= ext2fs_write_dir_block3(fs
, block_nr
, buf
, 0);
1136 if (cd
->pctx
.errcode
) {
1137 if (!fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
,
1139 goto abort_free_dict
;
1141 ext2fs_mark_changed(fs
);
1143 dict_free_nodes(&de_dict
);
1146 ctx
->flags
|= E2F_FLAG_ABORT
;
1147 dict_free_nodes(&de_dict
);
1148 return DIRENT_ABORT
;
1157 * This function is called to deallocate a block, and is an interator
1158 * functioned called by deallocate inode via ext2fs_iterate_block().
1160 static int deallocate_inode_block(ext2_filsys fs
,
1162 e2_blkcnt_t blockcnt
EXT2FS_ATTR((unused
)),
1163 blk64_t ref_block
EXT2FS_ATTR((unused
)),
1164 int ref_offset
EXT2FS_ATTR((unused
)),
1167 struct del_block
*p
= priv_data
;
1169 if (HOLE_BLKADDR(*block_nr
))
1171 if ((*block_nr
< fs
->super
->s_first_data_block
) ||
1172 (*block_nr
>= ext2fs_blocks_count(fs
->super
)))
1174 ext2fs_block_alloc_stats2(fs
, *block_nr
, -1);
1180 * This fuction deallocates an inode
1182 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
)
1184 ext2_filsys fs
= ctx
->fs
;
1185 struct ext2_inode inode
;
1186 struct problem_context pctx
;
1188 struct del_block del_block
;
1190 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
1191 clear_problem_context(&pctx
);
1195 * Fix up the bitmaps...
1197 e2fsck_read_bitmaps(ctx
);
1198 ext2fs_inode_alloc_stats2(fs
, ino
, -1, LINUX_S_ISDIR(inode
.i_mode
));
1200 if (ext2fs_file_acl_block(fs
, &inode
) &&
1201 (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
1202 pctx
.errcode
= ext2fs_adjust_ea_refcount2(fs
,
1203 ext2fs_file_acl_block(fs
, &inode
),
1204 block_buf
, -1, &count
);
1205 if (pctx
.errcode
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
1210 pctx
.blk
= ext2fs_file_acl_block(fs
, &inode
);
1211 fix_problem(ctx
, PR_2_ADJ_EA_REFCOUNT
, &pctx
);
1212 ctx
->flags
|= E2F_FLAG_ABORT
;
1216 ext2fs_block_alloc_stats2(fs
,
1217 ext2fs_file_acl_block(fs
, &inode
), -1);
1219 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1222 if (!ext2fs_inode_has_valid_blocks2(fs
, &inode
))
1225 if (LINUX_S_ISREG(inode
.i_mode
) &&
1226 ext2fs_needs_large_file_feature(EXT2_I_SIZE(&inode
)))
1229 del_block
.ctx
= ctx
;
1231 pctx
.errcode
= ext2fs_block_iterate3(fs
, ino
, 0, block_buf
,
1232 deallocate_inode_block
,
1235 fix_problem(ctx
, PR_2_DEALLOC_INODE
, &pctx
);
1236 ctx
->flags
|= E2F_FLAG_ABORT
;
1240 /* Inode may have changed by block_iterate, so reread it */
1241 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
1242 e2fsck_clear_inode(ctx
, ino
, &inode
, 0, "deallocate_inode");
1246 * This fuction clears the htree flag on an inode
1248 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
)
1250 struct ext2_inode inode
;
1252 e2fsck_read_inode(ctx
, ino
, &inode
, "clear_htree");
1253 inode
.i_flags
= inode
.i_flags
& ~EXT2_INDEX_FL
;
1254 e2fsck_write_inode(ctx
, ino
, &inode
, "clear_htree");
1255 if (ctx
->dirs_to_hash
)
1256 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
1260 int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
1261 ext2_ino_t ino
, char *buf
)
1263 ext2_filsys fs
= ctx
->fs
;
1264 struct ext2_inode inode
;
1265 int inode_modified
= 0;
1267 unsigned char *frag
, *fsize
;
1268 struct problem_context pctx
;
1269 problem_t problem
= 0;
1271 e2fsck_read_inode(ctx
, ino
, &inode
, "process_bad_inode");
1273 clear_problem_context(&pctx
);
1276 pctx
.inode
= &inode
;
1278 if (ext2fs_file_acl_block(fs
, &inode
) &&
1279 !(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
1280 if (fix_problem(ctx
, PR_2_FILE_ACL_ZERO
, &pctx
)) {
1281 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1287 if (!LINUX_S_ISDIR(inode
.i_mode
) && !LINUX_S_ISREG(inode
.i_mode
) &&
1288 !LINUX_S_ISCHR(inode
.i_mode
) && !LINUX_S_ISBLK(inode
.i_mode
) &&
1289 !LINUX_S_ISLNK(inode
.i_mode
) && !LINUX_S_ISFIFO(inode
.i_mode
) &&
1290 !(LINUX_S_ISSOCK(inode
.i_mode
)))
1291 problem
= PR_2_BAD_MODE
;
1292 else if (LINUX_S_ISCHR(inode
.i_mode
)
1293 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1294 problem
= PR_2_BAD_CHAR_DEV
;
1295 else if (LINUX_S_ISBLK(inode
.i_mode
)
1296 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1297 problem
= PR_2_BAD_BLOCK_DEV
;
1298 else if (LINUX_S_ISFIFO(inode
.i_mode
)
1299 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1300 problem
= PR_2_BAD_FIFO
;
1301 else if (LINUX_S_ISSOCK(inode
.i_mode
)
1302 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
1303 problem
= PR_2_BAD_SOCKET
;
1304 else if (LINUX_S_ISLNK(inode
.i_mode
)
1305 && !e2fsck_pass1_check_symlink(fs
, ino
, &inode
, buf
)) {
1306 problem
= PR_2_INVALID_SYMLINK
;
1310 if (fix_problem(ctx
, problem
, &pctx
)) {
1311 deallocate_inode(ctx
, ino
, 0);
1312 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
1320 if (inode
.i_faddr
) {
1321 if (fix_problem(ctx
, PR_2_FADDR_ZERO
, &pctx
)) {
1328 switch (fs
->super
->s_creator_os
) {
1330 frag
= &inode
.osd2
.hurd2
.h_i_frag
;
1331 fsize
= &inode
.osd2
.hurd2
.h_i_fsize
;
1336 if (frag
&& *frag
) {
1338 if (fix_problem(ctx
, PR_2_FRAG_ZERO
, &pctx
)) {
1345 if (fsize
&& *fsize
) {
1347 if (fix_problem(ctx
, PR_2_FSIZE_ZERO
, &pctx
)) {
1355 if ((fs
->super
->s_creator_os
== EXT2_OS_LINUX
) &&
1356 !(fs
->super
->s_feature_ro_compat
&
1357 EXT4_FEATURE_RO_COMPAT_HUGE_FILE
) &&
1358 (inode
.osd2
.linux2
.l_i_blocks_hi
!= 0)) {
1359 pctx
.num
= inode
.osd2
.linux2
.l_i_blocks_hi
;
1360 if (fix_problem(ctx
, PR_2_BLOCKS_HI_ZERO
, &pctx
)) {
1361 inode
.osd2
.linux2
.l_i_blocks_hi
= 0;
1366 if (!(fs
->super
->s_feature_incompat
&
1367 EXT4_FEATURE_INCOMPAT_64BIT
) &&
1368 inode
.osd2
.linux2
.l_i_file_acl_high
!= 0) {
1369 pctx
.num
= inode
.osd2
.linux2
.l_i_file_acl_high
;
1370 if (fix_problem(ctx
, PR_2_I_FILE_ACL_HI_ZERO
, &pctx
)) {
1371 inode
.osd2
.linux2
.l_i_file_acl_high
= 0;
1377 if (ext2fs_file_acl_block(fs
, &inode
) &&
1378 ((ext2fs_file_acl_block(fs
, &inode
) < fs
->super
->s_first_data_block
) ||
1379 (ext2fs_file_acl_block(fs
, &inode
) >= ext2fs_blocks_count(fs
->super
)))) {
1380 if (fix_problem(ctx
, PR_2_FILE_ACL_BAD
, &pctx
)) {
1381 ext2fs_file_acl_block_set(fs
, &inode
, 0);
1386 if (inode
.i_dir_acl
&&
1387 LINUX_S_ISDIR(inode
.i_mode
)) {
1388 if (fix_problem(ctx
, PR_2_DIR_ACL_ZERO
, &pctx
)) {
1389 inode
.i_dir_acl
= 0;
1396 e2fsck_write_inode(ctx
, ino
, &inode
, "process_bad_inode");
1397 if (!not_fixed
&& ctx
->inode_bad_map
)
1398 ext2fs_unmark_inode_bitmap2(ctx
->inode_bad_map
, ino
);
1404 * allocate_dir_block --- this function allocates a new directory
1405 * block for a particular inode; this is done if a directory has
1406 * a "hole" in it, or if a directory has a illegal block number
1407 * that was zeroed out and now needs to be replaced.
1409 static int allocate_dir_block(e2fsck_t ctx
,
1410 struct ext2_db_entry2
*db
,
1411 char *buf
EXT2FS_ATTR((unused
)),
1412 struct problem_context
*pctx
)
1414 ext2_filsys fs
= ctx
->fs
;
1417 struct ext2_inode inode
;
1419 if (fix_problem(ctx
, PR_2_DIRECTORY_HOLE
, pctx
) == 0)
1423 * Read the inode and block bitmaps in; we'll be messing with
1426 e2fsck_read_bitmaps(ctx
);
1429 * First, find a free block
1431 pctx
->errcode
= ext2fs_new_block2(fs
, 0, ctx
->block_found_map
, &blk
);
1432 if (pctx
->errcode
) {
1433 pctx
->str
= "ext2fs_new_block";
1434 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1437 ext2fs_mark_block_bitmap2(ctx
->block_found_map
, blk
);
1438 ext2fs_mark_block_bitmap2(fs
->block_map
, blk
);
1439 ext2fs_mark_bb_dirty(fs
);
1442 * Now let's create the actual data block for the inode
1445 pctx
->errcode
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
1447 pctx
->errcode
= ext2fs_new_dir_block(fs
, db
->ino
,
1448 EXT2_ROOT_INO
, &block
);
1450 if (pctx
->errcode
) {
1451 pctx
->str
= "ext2fs_new_dir_block";
1452 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1456 pctx
->errcode
= ext2fs_write_dir_block3(fs
, blk
, block
, 0);
1457 ext2fs_free_mem(&block
);
1458 if (pctx
->errcode
) {
1459 pctx
->str
= "ext2fs_write_dir_block";
1460 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
1465 * Update the inode block count
1467 e2fsck_read_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1468 ext2fs_iblk_add_blocks(fs
, &inode
, 1);
1469 if (inode
.i_size
< (db
->blockcnt
+1) * fs
->blocksize
)
1470 inode
.i_size
= (db
->blockcnt
+1) * fs
->blocksize
;
1471 e2fsck_write_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
1474 * Finally, update the block pointers for the inode
1477 pctx
->errcode
= ext2fs_bmap2(fs
, db
->ino
, &inode
, 0, BMAP_SET
,
1478 db
->blockcnt
, 0, &blk
);
1479 if (pctx
->errcode
) {
1480 pctx
->str
= "ext2fs_block_iterate";
1481 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);