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 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) 14 */ 15 16#include "config.h" 17#include "e2fsck.h" 18#include "problem.h" 19#include <ext2fs/ext2_ext_attr.h> 20 21/* 22 * This routine is called when an inode is not connected to the 23 * directory tree. 24 * 25 * This subroutine returns 1 then the caller shouldn't bother with the 26 * rest of the pass 4 tests. 27 */ 28static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i, 29 struct ext2_inode_large *inode) 30{ 31 ext2_filsys fs = ctx->fs; 32 struct problem_context pctx; 33 __u32 eamagic = 0; 34 int extra_size = 0; 35 36 e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode), 37 EXT2_INODE_SIZE(fs->super), 38 "pass4: disconnect_inode"); 39 if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE) 40 extra_size = inode->i_extra_isize; 41 clear_problem_context(&pctx); 42 pctx.ino = i; 43 pctx.inode = EXT2_INODE(inode); 44 45 if (EXT2_INODE_SIZE(fs->super) -EXT2_GOOD_OLD_INODE_SIZE -extra_size >0) 46 eamagic = *(__u32 *)(((char *)inode) +EXT2_GOOD_OLD_INODE_SIZE + 47 extra_size); 48 /* 49 * Offer to delete any zero-length files that does not have 50 * blocks. If there is an EA block, it might have useful 51 * information, so we won't prompt to delete it, but let it be 52 * reconnected to lost+found. 53 */ 54 if (!inode->i_blocks && eamagic != EXT2_EXT_ATTR_MAGIC && 55 (LINUX_S_ISREG(inode->i_mode) || LINUX_S_ISDIR(inode->i_mode))) { 56 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) { 57 e2fsck_clear_inode(ctx, i, EXT2_INODE(inode), 0, 58 "disconnect_inode"); 59 /* 60 * Fix up the bitmaps... 61 */ 62 e2fsck_read_bitmaps(ctx); 63 ext2fs_inode_alloc_stats2(fs, i, -1, 64 LINUX_S_ISDIR(inode->i_mode)); 65 quota_data_inodes(ctx->qctx, inode, i, -1); 66 return 0; 67 } 68 } 69 70 /* 71 * Prompt to reconnect. 72 */ 73 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) { 74 if (e2fsck_reconnect_file(ctx, i)) 75 ext2fs_unmark_valid(fs); 76 } else { 77 /* 78 * If we don't attach the inode, then skip the 79 * i_links_test since there's no point in trying to 80 * force i_links_count to zero. 81 */ 82 ext2fs_unmark_valid(fs); 83 return 1; 84 } 85 return 0; 86} 87 88 89void e2fsck_pass4(e2fsck_t ctx) 90{ 91 ext2_filsys fs = ctx->fs; 92 ext2_ino_t i; 93 struct ext2_inode_large *inode; 94 int inode_size = EXT2_INODE_SIZE(fs->super); 95#ifdef RESOURCE_TRACK 96 struct resource_track rtrack; 97#endif 98 struct problem_context pctx; 99 __u16 link_count, link_counted; 100 char *buf = 0; 101 dgrp_t group, maxgroup; 102 103 init_resource_track(&rtrack, ctx->fs->io); 104 105#ifdef MTRACE 106 mtrace_print("Pass 4"); 107#endif 108 /* 109 * Since pass4 is mostly CPU bound, start readahead of bitmaps 110 * ahead of pass 5 if we haven't already loaded them. 111 */ 112 if (ctx->readahead_kb && 113 (fs->block_map == NULL || fs->inode_map == NULL)) 114 e2fsck_readahead(fs, E2FSCK_READA_BBITMAP | 115 E2FSCK_READA_IBITMAP, 116 0, fs->group_desc_count); 117 118 clear_problem_context(&pctx); 119 120 if (!(ctx->options & E2F_OPT_PREEN)) 121 fix_problem(ctx, PR_4_PASS_HEADER, &pctx); 122 123 group = 0; 124 maxgroup = fs->group_desc_count; 125 if (ctx->progress) 126 if ((ctx->progress)(ctx, 4, 0, maxgroup)) 127 return; 128 129 inode = e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); 130 131 /* Protect loop from wrap-around if s_inodes_count maxed */ 132 for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) { 133 int isdir; 134 135 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 136 goto errout; 137 if ((i % fs->super->s_inodes_per_group) == 0) { 138 group++; 139 if (ctx->progress) 140 if ((ctx->progress)(ctx, 4, group, maxgroup)) 141 goto errout; 142 } 143 if (i == quota_type2inum(PRJQUOTA, ctx->fs->super) || 144 i == EXT2_BAD_INO || 145 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) 146 continue; 147 if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) || 148 (ctx->inode_imagic_map && 149 ext2fs_test_inode_bitmap2(ctx->inode_imagic_map, i)) || 150 (ctx->inode_bb_map && 151 ext2fs_test_inode_bitmap2(ctx->inode_bb_map, i))) 152 continue; 153 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); 154 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); 155 if (link_counted == 0) { 156 if (!buf) 157 buf = e2fsck_allocate_memory(ctx, 158 fs->blocksize, "bad_inode buffer"); 159 if (e2fsck_process_bad_inode(ctx, 0, i, buf)) 160 continue; 161 if (disconnect_inode(ctx, i, inode)) 162 continue; 163 ext2fs_icount_fetch(ctx->inode_link_info, i, 164 &link_count); 165 ext2fs_icount_fetch(ctx->inode_count, i, 166 &link_counted); 167 } 168 isdir = ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i); 169 if (isdir && (link_counted > EXT2_LINK_MAX)) 170 link_counted = 1; 171 if (link_counted != link_count) { 172 e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode), 173 inode_size, "pass4"); 174 pctx.ino = i; 175 pctx.inode = EXT2_INODE(inode); 176 if ((link_count != inode->i_links_count) && !isdir && 177 (inode->i_links_count <= EXT2_LINK_MAX)) { 178 pctx.num = link_count; 179 fix_problem(ctx, 180 PR_4_INCONSISTENT_COUNT, &pctx); 181 } 182 pctx.num = link_counted; 183 /* i_link_count was previously exceeded, but no longer 184 * is, fix this but don't consider it an error */ 185 if ((isdir && link_counted > 1 && 186 (inode->i_flags & EXT2_INDEX_FL) && 187 link_count == 1 && !(ctx->options & E2F_OPT_NO)) || 188 fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) { 189 inode->i_links_count = link_counted; 190 e2fsck_write_inode_full(ctx, i, 191 EXT2_INODE(inode), 192 inode_size, "pass4"); 193 } 194 } 195 } 196 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; 197 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; 198 ext2fs_free_inode_bitmap(ctx->inode_bb_map); 199 ctx->inode_bb_map = 0; 200 ext2fs_free_inode_bitmap(ctx->inode_imagic_map); 201 ctx->inode_imagic_map = 0; 202errout: 203 if (buf) 204 ext2fs_free_mem(&buf); 205 206 ext2fs_free_mem(&inode); 207 print_resource_track(ctx, _("Pass 4"), &rtrack, ctx->fs->io); 208} 209 210