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