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