pass4.c revision 21c84b71e205b5ab13f14343da5645dcc985856d
1/* 2 * pass4.c -- pass #4 of e2fsck: Check reference counts 3 * 4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 * 11 * Pass 4 frees the following data structures: 12 * - A bitmap of which inodes are in bad blocks. (inode_bb_map) 13 */ 14 15#include "e2fsck.h" 16#include "problem.h" 17 18/* 19 * This routine is called when an inode is not connected to the 20 * directory tree. 21 * 22 * This subroutine returns 1 then the caller shouldn't bother with the 23 * rest of the pass 4 tests. 24 */ 25static int disconnect_inode(ext2_filsys fs, ino_t i) 26{ 27 struct ext2_inode inode; 28 struct problem_context pctx; 29 30 e2fsck_read_inode(fs, i, &inode, "pass4: disconnect_inode"); 31 clear_problem_context(&pctx); 32 pctx.ino = i; 33 pctx.inode = &inode; 34 35 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) || 36 LINUX_S_ISDIR(inode.i_mode))) { 37 /* 38 * This is a zero-length file; prompt to delete it... 39 */ 40 if (fix_problem(fs, PR_4_ZERO_LEN_INODE, &pctx)) { 41 ext2fs_icount_store(inode_link_info, i, 0); 42 inode.i_links_count = 0; 43 inode.i_dtime = time(0); 44 e2fsck_write_inode(fs, i, &inode, 45 "disconnect_inode"); 46 /* 47 * Fix up the bitmaps... 48 */ 49 read_bitmaps(fs); 50 ext2fs_unmark_inode_bitmap(inode_used_map, i); 51 ext2fs_unmark_inode_bitmap(inode_dir_map, i); 52 ext2fs_unmark_inode_bitmap(fs->inode_map, i); 53 ext2fs_mark_ib_dirty(fs); 54 return 0; 55 } 56 } 57 58 /* 59 * Prompt to reconnect. 60 */ 61 if (fix_problem(fs, PR_4_UNATTACHED_INODE, &pctx)) { 62 if (reconnect_file(fs, i)) 63 ext2fs_unmark_valid(fs); 64 } else { 65 /* 66 * If we don't attach the inode, then skip the 67 * i_links_test since there's no point in trying to 68 * force i_links_count to zero. 69 */ 70 ext2fs_unmark_valid(fs); 71 return 1; 72 } 73 return 0; 74} 75 76 77void pass4(ext2_filsys fs) 78{ 79 ino_t i; 80 struct ext2_inode inode; 81 struct resource_track rtrack; 82 struct problem_context pctx; 83 __u16 link_count, link_counted; 84 85 init_resource_track(&rtrack); 86 87#ifdef MTRACE 88 mtrace_print("Pass 4"); 89#endif 90 91 if (!preen) 92 printf("Pass 4: Checking reference counts\n"); 93 clear_problem_context(&pctx); 94 for (i=1; i <= fs->super->s_inodes_count; i++) { 95 if (i == EXT2_BAD_INO || 96 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) 97 continue; 98 if (!(ext2fs_test_inode_bitmap(inode_used_map, i)) || 99 (inode_bb_map && 100 ext2fs_test_inode_bitmap(inode_bb_map, i))) 101 continue; 102 ext2fs_icount_fetch(inode_link_info, i, &link_count); 103 ext2fs_icount_fetch(inode_count, i, &link_counted); 104 if (link_counted == 0) { 105 if (disconnect_inode(fs, i)) 106 continue; 107 ext2fs_icount_fetch(inode_link_info, i, &link_count); 108 ext2fs_icount_fetch(inode_count, i, &link_counted); 109 } 110 if (link_counted != link_count) { 111 e2fsck_read_inode(fs, i, &inode, "pass4"); 112 pctx.ino = i; 113 pctx.inode = &inode; 114 if (link_count != inode.i_links_count) { 115 printf("WARNING: PROGRAMMING BUG IN E2FSCK!\n"); 116 printf("\tOR SOME BONEHEAD (YOU) IS CHECKING " 117 "A MOUNTED (LIVE) FILESYSTEM.\n"); 118 printf("inode_link_info[%ld] is %u, " 119 "inode.i_links_count is %d. " 120 "They should be the same!\n", 121 i, link_count, 122 inode.i_links_count); 123 } 124 pctx.num = link_counted; 125 if (fix_problem(fs, PR_4_BAD_REF_COUNT, &pctx)) { 126 inode.i_links_count = link_counted; 127 e2fsck_write_inode(fs, i, &inode, "pass4"); 128 } 129 } 130 } 131 ext2fs_free_icount(inode_link_info); inode_link_info = 0; 132 ext2fs_free_icount(inode_count); inode_count = 0; 133 ext2fs_free_inode_bitmap(inode_bb_map); 134 if (tflag > 1) { 135 printf("Pass 4: "); 136 print_resource_track(&rtrack); 137 } 138} 139 140