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
54 * Keeps track of how many times an inode is referenced.
56 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
);
57 static int check_dir_block(ext2_filsys fs
,
58 struct ext2_db_entry
*dir_blocks_info
,
60 static int allocate_dir_block(e2fsck_t ctx
,
61 struct ext2_db_entry
*dir_blocks_info
,
62 char *buf
, struct problem_context
*pctx
);
63 static int update_dir_block(ext2_filsys fs
,
70 struct check_dir_struct
{
72 struct problem_context pctx
;
77 void e2fsck_pass2(e2fsck_t ctx
)
79 struct ext2_super_block
*sb
= ctx
->fs
->super
;
80 struct problem_context pctx
;
81 ext2_filsys fs
= ctx
->fs
;
84 struct resource_track rtrack
;
87 struct check_dir_struct cd
;
90 init_resource_track(&rtrack
);
93 clear_problem_context(&cd
.pctx
);
96 mtrace_print("Pass 2");
99 if (!(ctx
->options
& E2F_OPT_PREEN
))
100 fix_problem(ctx
, PR_2_PASS_HEADER
, &cd
.pctx
);
102 cd
.pctx
.errcode
= ext2fs_create_icount2(fs
, EXT2_ICOUNT_OPT_INCREMENT
,
103 0, ctx
->inode_link_info
,
105 if (cd
.pctx
.errcode
) {
106 fix_problem(ctx
, PR_2_ALLOCATE_ICOUNT
, &cd
.pctx
);
107 ctx
->flags
|= E2F_FLAG_ABORT
;
110 buf
= (char *) e2fsck_allocate_memory(ctx
, 2*fs
->blocksize
,
111 "directory scan buffer");
114 * Set up the parent pointer for the root directory, if
115 * present. (If the root directory is not present, we will
116 * create it in pass 3.)
118 dir
= e2fsck_get_dir_info(ctx
, EXT2_ROOT_INO
);
120 dir
->parent
= EXT2_ROOT_INO
;
125 cd
.max
= ext2fs_dblist_count(fs
->dblist
);
128 (void) (ctx
->progress
)(ctx
, 2, 0, cd
.max
);
130 cd
.pctx
.errcode
= ext2fs_dblist_iterate(fs
->dblist
, check_dir_block
,
132 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
134 if (cd
.pctx
.errcode
) {
135 fix_problem(ctx
, PR_2_DBLIST_ITERATE
, &cd
.pctx
);
136 ctx
->flags
|= E2F_FLAG_ABORT
;
140 ext2fs_free_mem((void **) &buf
);
141 ext2fs_free_dblist(fs
->dblist
);
143 if (ctx
->inode_bad_map
) {
144 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
145 ctx
->inode_bad_map
= 0;
147 if (ctx
->inode_reg_map
) {
148 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
149 ctx
->inode_reg_map
= 0;
152 clear_problem_context(&pctx
);
153 if (ctx
->large_files
) {
154 if (!(sb
->s_feature_ro_compat
&
155 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
) &&
156 fix_problem(ctx
, PR_2_FEATURE_LARGE_FILES
, &pctx
)) {
157 sb
->s_feature_ro_compat
|=
158 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
159 ext2fs_mark_super_dirty(fs
);
161 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
162 fix_problem(ctx
, PR_1_FS_REV_LEVEL
, &pctx
)) {
163 ext2fs_update_dynamic_rev(fs
);
164 ext2fs_mark_super_dirty(fs
);
166 } else if (!ctx
->large_files
&&
167 (sb
->s_feature_ro_compat
&
168 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
)) {
169 if (fs
->flags
& EXT2_FLAG_RW
) {
170 sb
->s_feature_ro_compat
&=
171 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
172 ext2fs_mark_super_dirty(fs
);
176 #ifdef RESOURCE_TRACK
177 if (ctx
->options
& E2F_OPT_TIME2
) {
178 e2fsck_clear_progbar(ctx
);
179 print_resource_track("Pass 2", &rtrack
);
185 * Make sure the first entry in the directory is '.', and that the
186 * directory entry is sane.
188 static int check_dot(e2fsck_t ctx
,
189 struct ext2_dir_entry
*dirent
,
190 ext2_ino_t ino
, struct problem_context
*pctx
)
192 struct ext2_dir_entry
*nextdir
;
199 problem
= PR_2_MISSING_DOT
;
200 else if (((dirent
->name_len
& 0xFF) != 1) ||
201 (dirent
->name
[0] != '.'))
202 problem
= PR_2_1ST_NOT_DOT
;
203 else if (dirent
->name
[1] != '\0')
204 problem
= PR_2_DOT_NULL_TERM
;
207 if (fix_problem(ctx
, problem
, pctx
)) {
208 if (dirent
->rec_len
< 12)
209 dirent
->rec_len
= 12;
211 dirent
->name_len
= 1;
212 dirent
->name
[0] = '.';
213 dirent
->name
[1] = '\0';
218 if (dirent
->inode
!= ino
) {
219 if (fix_problem(ctx
, PR_2_BAD_INODE_DOT
, pctx
)) {
224 if (dirent
->rec_len
> 12) {
225 new_len
= dirent
->rec_len
- 12;
228 fix_problem(ctx
, PR_2_SPLIT_DOT
, pctx
)) {
229 nextdir
= (struct ext2_dir_entry
*)
230 ((char *) dirent
+ 12);
231 dirent
->rec_len
= 12;
232 nextdir
->rec_len
= new_len
;
234 nextdir
->name_len
= 0;
243 * Make sure the second entry in the directory is '..', and that the
244 * directory entry is sane. We do not check the inode number of '..'
245 * here; this gets done in pass 3.
247 static int check_dotdot(e2fsck_t ctx
,
248 struct ext2_dir_entry
*dirent
,
249 struct dir_info
*dir
, struct problem_context
*pctx
)
254 problem
= PR_2_MISSING_DOT_DOT
;
255 else if (((dirent
->name_len
& 0xFF) != 2) ||
256 (dirent
->name
[0] != '.') ||
257 (dirent
->name
[1] != '.'))
258 problem
= PR_2_2ND_NOT_DOT_DOT
;
259 else if (dirent
->name
[2] != '\0')
260 problem
= PR_2_DOT_DOT_NULL_TERM
;
263 if (fix_problem(ctx
, problem
, pctx
)) {
264 if (dirent
->rec_len
< 12)
265 dirent
->rec_len
= 12;
267 * Note: we don't have the parent inode just
268 * yet, so we will fill it in with the root
269 * inode. This will get fixed in pass 3.
271 dirent
->inode
= EXT2_ROOT_INO
;
272 dirent
->name_len
= 2;
273 dirent
->name
[0] = '.';
274 dirent
->name
[1] = '.';
275 dirent
->name
[2] = '\0';
280 dir
->dotdot
= dirent
->inode
;
285 * Check to make sure a directory entry doesn't contain any illegal
288 static int check_name(e2fsck_t ctx
,
289 struct ext2_dir_entry
*dirent
,
290 ext2_ino_t dir_ino
, struct problem_context
*pctx
)
296 for ( i
= 0; i
< (dirent
->name_len
& 0xFF); i
++) {
297 if (dirent
->name
[i
] == '/' || dirent
->name
[i
] == '\0') {
299 fixup
= fix_problem(ctx
, PR_2_BAD_NAME
, pctx
);
302 dirent
->name
[i
] = '.';
311 * Check the directory filetype (if present)
313 static _INLINE_
int check_filetype(e2fsck_t ctx
,
314 struct ext2_dir_entry
*dirent
,
315 ext2_ino_t dir_ino
, struct problem_context
*pctx
)
317 int filetype
= dirent
->name_len
>> 8;
318 int should_be
= EXT2_FT_UNKNOWN
;
319 struct ext2_inode inode
;
321 if (!(ctx
->fs
->super
->s_feature_incompat
&
322 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
324 !fix_problem(ctx
, PR_2_CLEAR_FILETYPE
, pctx
))
326 dirent
->name_len
= dirent
->name_len
& 0xFF;
330 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, dirent
->inode
)) {
331 should_be
= EXT2_FT_DIR
;
332 } else if (ext2fs_test_inode_bitmap(ctx
->inode_reg_map
,
334 should_be
= EXT2_FT_REG_FILE
;
335 } else if (ctx
->inode_bad_map
&&
336 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
340 e2fsck_read_inode(ctx
, dirent
->inode
, &inode
,
342 should_be
= ext2_file_type(inode
.i_mode
);
344 if (filetype
== should_be
)
346 pctx
->num
= should_be
;
348 if (fix_problem(ctx
, filetype
? PR_2_BAD_FILETYPE
: PR_2_SET_FILETYPE
,
352 dirent
->name_len
= (dirent
->name_len
& 0xFF) | should_be
<< 8;
357 static int check_dir_block(ext2_filsys fs
,
358 struct ext2_db_entry
*db
,
361 struct dir_info
*subdir
, *dir
;
362 struct ext2_dir_entry
*dirent
;
364 int dir_modified
= 0;
366 blk_t block_nr
= db
->blk
;
367 ext2_ino_t ino
= db
->ino
;
369 struct check_dir_struct
*cd
;
374 cd
= (struct check_dir_struct
*) priv_data
;
379 if ((ctx
->progress
)(ctx
, 2, cd
->count
++, cd
->max
))
383 * Make sure the inode is still in use (could have been
384 * deleted in the duplicate/bad blocks pass.
386 if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
, ino
)))
390 cd
->pctx
.blk
= block_nr
;
391 cd
->pctx
.blkcount
= db
->blockcnt
;
397 if (allocate_dir_block(ctx
, db
, buf
, &cd
->pctx
))
408 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr
,
412 cd
->pctx
.errcode
= ext2fs_read_dir_block(fs
, block_nr
, buf
);
413 if (cd
->pctx
.errcode
== EXT2_ET_DIR_CORRUPTED
)
414 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
415 if (cd
->pctx
.errcode
) {
416 if (!fix_problem(ctx
, PR_2_READ_DIRBLOCK
, &cd
->pctx
)) {
417 ctx
->flags
|= E2F_FLAG_ABORT
;
420 memset(buf
, 0, fs
->blocksize
);
426 dirent
= (struct ext2_dir_entry
*) (buf
+ offset
);
427 cd
->pctx
.dirent
= dirent
;
428 cd
->pctx
.num
= offset
;
429 if (((offset
+ dirent
->rec_len
) > fs
->blocksize
) ||
430 (dirent
->rec_len
< 12) ||
431 ((dirent
->rec_len
% 4) != 0) ||
432 (((dirent
->name_len
& 0xFF)+8) > dirent
->rec_len
)) {
433 if (fix_problem(ctx
, PR_2_DIR_CORRUPTED
, &cd
->pctx
)) {
434 dirent
->rec_len
= fs
->blocksize
- offset
;
435 dirent
->name_len
= 0;
441 if ((dirent
->name_len
& 0xFF) > EXT2_NAME_LEN
) {
442 if (fix_problem(ctx
, PR_2_FILENAME_LONG
, &cd
->pctx
)) {
443 dirent
->name_len
= EXT2_NAME_LEN
;
448 if (dot_state
== 1) {
449 if (check_dot(ctx
, dirent
, ino
, &cd
->pctx
))
451 } else if (dot_state
== 2) {
452 dir
= e2fsck_get_dir_info(ctx
, ino
);
454 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
455 ctx
->flags
|= E2F_FLAG_ABORT
;
458 if (check_dotdot(ctx
, dirent
, dir
, &cd
->pctx
))
460 } else if (dirent
->inode
== ino
) {
461 problem
= PR_2_LINK_DOT
;
462 if (fix_problem(ctx
, PR_2_LINK_DOT
, &cd
->pctx
)) {
472 * Make sure the inode listed is a legal one.
474 if (((dirent
->inode
!= EXT2_ROOT_INO
) &&
475 (dirent
->inode
< EXT2_FIRST_INODE(fs
->super
))) ||
476 (dirent
->inode
> fs
->super
->s_inodes_count
)) {
477 problem
= PR_2_BAD_INO
;
478 } else if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
,
481 * If the inode is unused, offer to clear it.
483 problem
= PR_2_UNUSED_INODE
;
484 } else if (ctx
->inode_bb_map
&&
485 (ext2fs_test_inode_bitmap(ctx
->inode_bb_map
,
488 * If the inode is in a bad block, offer to
491 problem
= PR_2_BB_INODE
;
492 } else if ((dot_state
> 2) &&
493 ((dirent
->name_len
& 0xFF) == 1) &&
494 (dirent
->name
[0] == '.')) {
496 * If there's a '.' entry in anything other
497 * than the first directory entry, it's a
498 * duplicate entry that should be removed.
500 problem
= PR_2_DUP_DOT
;
501 } else if ((dot_state
> 2) &&
502 ((dirent
->name_len
& 0xFF) == 2) &&
503 (dirent
->name
[0] == '.') &&
504 (dirent
->name
[1] == '.')) {
506 * If there's a '..' entry in anything other
507 * than the second directory entry, it's a
508 * duplicate entry that should be removed.
510 problem
= PR_2_DUP_DOT_DOT
;
511 } else if ((dot_state
> 2) &&
512 (dirent
->inode
== EXT2_ROOT_INO
)) {
514 * Don't allow links to the root directory.
515 * We check this specially to make sure we
516 * catch this error case even if the root
517 * directory hasn't been created yet.
519 problem
= PR_2_LINK_ROOT
;
520 } else if ((dot_state
> 2) &&
521 (dirent
->name_len
& 0xFF) == 0) {
523 * Don't allow zero-length directory names.
525 problem
= PR_2_NULL_NAME
;
529 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
534 ext2fs_unmark_valid(fs
);
535 if (problem
== PR_2_BAD_INO
)
541 * If the inode was marked as having bad fields in
542 * pass1, process it and offer to fix/clear it.
543 * (We wait until now so that we can display the
544 * pathname to the user.)
546 if (ctx
->inode_bad_map
&&
547 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
549 if (e2fsck_process_bad_inode(ctx
, ino
,
551 buf
+ fs
->blocksize
)) {
556 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
560 if (check_name(ctx
, dirent
, ino
, &cd
->pctx
))
563 if (check_filetype(ctx
, dirent
, ino
, &cd
->pctx
))
567 * If this is a directory, then mark its parent in its
568 * dir_info structure. If the parent field is already
569 * filled in, then this directory has more than one
570 * hard link. We assume the first link is correct,
571 * and ask the user if he/she wants to clear this one.
573 if ((dot_state
> 2) &&
574 (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
,
576 subdir
= e2fsck_get_dir_info(ctx
, dirent
->inode
);
578 cd
->pctx
.ino
= dirent
->inode
;
579 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
580 ctx
->flags
|= E2F_FLAG_ABORT
;
583 if (subdir
->parent
) {
584 cd
->pctx
.ino2
= subdir
->parent
;
585 if (fix_problem(ctx
, PR_2_LINK_DIR
,
593 subdir
->parent
= ino
;
596 ext2fs_icount_increment(ctx
->inode_count
, dirent
->inode
,
599 ctx
->fs_links_count
++;
600 ctx
->fs_total_count
++;
602 offset
+= dirent
->rec_len
;
603 } while (offset
< fs
->blocksize
);
607 if (offset
!= fs
->blocksize
) {
608 cd
->pctx
.num
= dirent
->rec_len
- fs
->blocksize
+ offset
;
609 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
610 dirent
->rec_len
= cd
->pctx
.num
;
615 cd
->pctx
.errcode
= ext2fs_write_dir_block(fs
, block_nr
, buf
);
616 if (cd
->pctx
.errcode
) {
617 if (!fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
,
619 ctx
->flags
|= E2F_FLAG_ABORT
;
623 ext2fs_mark_changed(fs
);
629 * This function is called to deallocate a block, and is an interator
630 * functioned called by deallocate inode via ext2fs_iterate_block().
632 static int deallocate_inode_block(ext2_filsys fs
,
634 e2_blkcnt_t blockcnt
,
639 e2fsck_t ctx
= (e2fsck_t
) priv_data
;
641 if (HOLE_BLKADDR(*block_nr
))
643 ext2fs_unmark_block_bitmap(ctx
->block_found_map
, *block_nr
);
644 ext2fs_unmark_block_bitmap(fs
->block_map
, *block_nr
);
649 * This fuction deallocates an inode
651 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
)
653 ext2_filsys fs
= ctx
->fs
;
654 struct ext2_inode inode
;
655 struct problem_context pctx
;
657 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 0);
658 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
659 inode
.i_links_count
= 0;
660 inode
.i_dtime
= time(0);
661 e2fsck_write_inode(ctx
, ino
, &inode
, "deallocate_inode");
662 clear_problem_context(&pctx
);
666 * Fix up the bitmaps...
668 e2fsck_read_bitmaps(ctx
);
669 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, ino
);
670 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, ino
);
671 if (ctx
->inode_bad_map
)
672 ext2fs_unmark_inode_bitmap(ctx
->inode_bad_map
, ino
);
673 ext2fs_unmark_inode_bitmap(fs
->inode_map
, ino
);
674 ext2fs_mark_ib_dirty(fs
);
676 if (!ext2fs_inode_has_valid_blocks(&inode
))
679 if (LINUX_S_ISREG(inode
.i_mode
) &&
680 (inode
.i_size_high
|| inode
.i_size
& 0x80000000UL
))
683 if (inode
.i_file_acl
) {
684 ext2fs_unmark_block_bitmap(ctx
->block_found_map
,
686 ext2fs_unmark_block_bitmap(fs
->block_map
, inode
.i_file_acl
);
689 ext2fs_mark_bb_dirty(fs
);
690 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
691 deallocate_inode_block
, ctx
);
693 fix_problem(ctx
, PR_2_DEALLOC_INODE
, &pctx
);
694 ctx
->flags
|= E2F_FLAG_ABORT
;
699 extern int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
700 ext2_ino_t ino
, char *buf
)
702 ext2_filsys fs
= ctx
->fs
;
703 struct ext2_inode inode
;
704 int inode_modified
= 0;
705 unsigned char *frag
, *fsize
;
706 struct problem_context pctx
;
709 e2fsck_read_inode(ctx
, ino
, &inode
, "process_bad_inode");
711 clear_problem_context(&pctx
);
716 if (!LINUX_S_ISDIR(inode
.i_mode
) && !LINUX_S_ISREG(inode
.i_mode
) &&
717 !LINUX_S_ISCHR(inode
.i_mode
) && !LINUX_S_ISBLK(inode
.i_mode
) &&
718 !LINUX_S_ISLNK(inode
.i_mode
) && !LINUX_S_ISFIFO(inode
.i_mode
) &&
719 !(LINUX_S_ISSOCK(inode
.i_mode
)))
720 problem
= PR_2_BAD_MODE
;
721 else if (LINUX_S_ISCHR(inode
.i_mode
)
722 && !e2fsck_pass1_check_device_inode(&inode
))
723 problem
= PR_2_BAD_CHAR_DEV
;
724 else if (LINUX_S_ISBLK(inode
.i_mode
)
725 && !e2fsck_pass1_check_device_inode(&inode
))
726 problem
= PR_2_BAD_BLOCK_DEV
;
727 else if (LINUX_S_ISFIFO(inode
.i_mode
)
728 && !e2fsck_pass1_check_device_inode(&inode
))
729 problem
= PR_2_BAD_FIFO
;
730 else if (LINUX_S_ISSOCK(inode
.i_mode
)
731 && !e2fsck_pass1_check_device_inode(&inode
))
732 problem
= PR_2_BAD_SOCKET
;
733 else if (LINUX_S_ISLNK(inode
.i_mode
)
734 && !e2fsck_pass1_check_symlink(fs
, &inode
, buf
)) {
735 problem
= PR_2_INVALID_SYMLINK
;
739 if (fix_problem(ctx
, problem
, &pctx
)) {
740 deallocate_inode(ctx
, ino
, 0);
741 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
749 fix_problem(ctx
, PR_2_FADDR_ZERO
, &pctx
)) {
754 switch (fs
->super
->s_creator_os
) {
756 frag
= &inode
.osd2
.linux2
.l_i_frag
;
757 fsize
= &inode
.osd2
.linux2
.l_i_fsize
;
760 frag
= &inode
.osd2
.hurd2
.h_i_frag
;
761 fsize
= &inode
.osd2
.hurd2
.h_i_fsize
;
764 frag
= &inode
.osd2
.masix2
.m_i_frag
;
765 fsize
= &inode
.osd2
.masix2
.m_i_fsize
;
772 if (fix_problem(ctx
, PR_2_FRAG_ZERO
, &pctx
)) {
778 if (fsize
&& *fsize
) {
780 if (fix_problem(ctx
, PR_2_FSIZE_ZERO
, &pctx
)) {
787 if (inode
.i_file_acl
&&
788 !(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
) &&
789 fix_problem(ctx
, PR_2_FILE_ACL_ZERO
, &pctx
)) {
790 inode
.i_file_acl
= 0;
793 if (inode
.i_file_acl
&&
794 ((inode
.i_file_acl
< fs
->super
->s_first_data_block
) ||
795 (inode
.i_file_acl
>= fs
->super
->s_blocks_count
)) &&
796 fix_problem(ctx
, PR_2_FILE_ACL_BAD
, &pctx
)) {
797 inode
.i_file_acl
= 0;
800 if (inode
.i_dir_acl
&&
801 LINUX_S_ISDIR(inode
.i_mode
) &&
802 fix_problem(ctx
, PR_2_DIR_ACL_ZERO
, &pctx
)) {
807 e2fsck_write_inode(ctx
, ino
, &inode
, "process_bad_inode");
813 * allocate_dir_block --- this function allocates a new directory
814 * block for a particular inode; this is done if a directory has
815 * a "hole" in it, or if a directory has a illegal block number
816 * that was zeroed out and now needs to be replaced.
818 static int allocate_dir_block(e2fsck_t ctx
,
819 struct ext2_db_entry
*db
,
820 char *buf
, struct problem_context
*pctx
)
822 ext2_filsys fs
= ctx
->fs
;
825 struct ext2_inode inode
;
827 if (fix_problem(ctx
, PR_2_DIRECTORY_HOLE
, pctx
) == 0)
831 * Read the inode and block bitmaps in; we'll be messing with
834 e2fsck_read_bitmaps(ctx
);
837 * First, find a free block
839 pctx
->errcode
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
, &blk
);
841 pctx
->str
= "ext2fs_new_block";
842 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
845 ext2fs_mark_block_bitmap(ctx
->block_found_map
, blk
);
846 ext2fs_mark_block_bitmap(fs
->block_map
, blk
);
847 ext2fs_mark_bb_dirty(fs
);
850 * Now let's create the actual data block for the inode
853 pctx
->errcode
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
855 pctx
->errcode
= ext2fs_new_dir_block(fs
, db
->ino
,
856 EXT2_ROOT_INO
, &block
);
859 pctx
->str
= "ext2fs_new_dir_block";
860 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
864 pctx
->errcode
= ext2fs_write_dir_block(fs
, blk
, block
);
865 ext2fs_free_mem((void **) &block
);
867 pctx
->str
= "ext2fs_write_dir_block";
868 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
873 * Update the inode block count
875 e2fsck_read_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
876 inode
.i_blocks
+= fs
->blocksize
/ 512;
877 if (inode
.i_size
< (db
->blockcnt
+1) * fs
->blocksize
)
878 inode
.i_size
= (db
->blockcnt
+1) * fs
->blocksize
;
879 e2fsck_write_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
882 * Finally, update the block pointers for the inode
885 pctx
->errcode
= ext2fs_block_iterate2(fs
, db
->ino
, BLOCK_FLAG_HOLE
,
886 0, update_dir_block
, db
);
888 pctx
->str
= "ext2fs_block_iterate";
889 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
897 * This is a helper function for allocate_dir_block().
899 static int update_dir_block(ext2_filsys fs
,
901 e2_blkcnt_t blockcnt
,
906 struct ext2_db_entry
*db
;
908 db
= (struct ext2_db_entry
*) priv_data
;
909 if (db
->blockcnt
== (int) blockcnt
) {
911 return BLOCK_CHANGED
;