Whamcloud - gitweb
Merge branch 'maint' into next
[tools/e2fsprogs.git] / e2fsck / pass4.c
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  *      - Ref counts for ea_inodes.                     (ea_inode_refs)
15  */
16
17 #include "config.h"
18 #include "e2fsck.h"
19 #include "problem.h"
20 #include <ext2fs/ext2_ext_attr.h>
21
22 /*
23  * This routine is called when an inode is not connected to the
24  * directory tree.
25  *
26  * This subroutine returns 1 then the caller shouldn't bother with the
27  * rest of the pass 4 tests.
28  */
29 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
30                             struct ext2_inode_large *inode)
31 {
32         ext2_filsys fs = ctx->fs;
33         struct problem_context  pctx;
34         __u32 eamagic = 0;
35         int extra_size = 0;
36
37         if (*last_ino != i) {
38                 e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
39                                        EXT2_INODE_SIZE(fs->super),
40                                        "pass4: disconnect_inode");
41                 *last_ino = i;
42         }
43         if (EXT2_INODE_SIZE(fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
44                 extra_size = inode->i_extra_isize;
45
46         clear_problem_context(&pctx);
47         pctx.ino = i;
48         pctx.inode = EXT2_INODE(inode);
49
50         if (EXT2_INODE_SIZE(fs->super) -EXT2_GOOD_OLD_INODE_SIZE -extra_size >0)
51                 eamagic = *(__u32 *)(((char *)inode) +EXT2_GOOD_OLD_INODE_SIZE +
52                                      extra_size);
53         /*
54          * Offer to delete any zero-length files that does not have
55          * blocks.  If there is an EA block, it might have useful
56          * information, so we won't prompt to delete it, but let it be
57          * reconnected to lost+found.
58          */
59         if (!inode->i_blocks && eamagic != EXT2_EXT_ATTR_MAGIC &&
60             (LINUX_S_ISREG(inode->i_mode) || LINUX_S_ISDIR(inode->i_mode))) {
61                 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
62                         e2fsck_clear_inode(ctx, i, EXT2_INODE(inode), 0,
63                                            "disconnect_inode");
64                         /*
65                          * Fix up the bitmaps...
66                          */
67                         e2fsck_read_bitmaps(ctx);
68                         ext2fs_inode_alloc_stats2(fs, i, -1,
69                                                   LINUX_S_ISDIR(inode->i_mode));
70                         quota_data_inodes(ctx->qctx, inode, i, -1);
71                         return 0;
72                 }
73         }
74
75         /*
76          * Prompt to reconnect.
77          */
78         if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
79                 if (e2fsck_reconnect_file(ctx, i))
80                         ext2fs_unmark_valid(fs);
81                 *last_ino = 0;
82         } else {
83                 /*
84                  * If we don't attach the inode, then skip the
85                  * i_links_test since there's no point in trying to
86                  * force i_links_count to zero.
87                  */
88                 ext2fs_unmark_valid(fs);
89                 return 1;
90         }
91         return 0;
92 }
93
94 /*
95  * This function is called when link_counted is zero. So this may not be
96  * an xattr inode at all. Return immediately if EA_INODE flag is not set.
97  */
98 static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino,
99                            struct ext2_inode_large *inode, __u16 *link_counted)
100 {
101         __u64 actual_refs = 0;
102         __u64 ref_count;
103
104         if (*last_ino != i) {
105                 e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
106                                        EXT2_INODE_SIZE(ctx->fs->super),
107                                        "pass4: check_ea_inode");
108                 *last_ino = i;
109         }
110         if (!(inode->i_flags & EXT4_EA_INODE_FL))
111                 return;
112
113         if (ctx->ea_inode_refs)
114                 ea_refcount_fetch(ctx->ea_inode_refs, i, &actual_refs);
115         if (!actual_refs)
116                 return;
117
118         /*
119          * There are some attribute references, link_counted is now considered
120          * to be 1.
121          */
122         *link_counted = 1;
123
124         ref_count = ext2fs_get_ea_inode_ref(EXT2_INODE(inode));
125
126         /* Old Lustre-style xattr inodes do not have a stored refcount.
127          * However, their i_ctime and i_atime should be the same.
128          */
129         if (ref_count != actual_refs && inode->i_ctime != inode->i_atime) {
130                 struct problem_context pctx;
131
132                 clear_problem_context(&pctx);
133                 pctx.ino = i;
134                 pctx.num = ref_count;
135                 pctx.num2 = actual_refs;
136                 if (fix_problem(ctx, PR_4_EA_INODE_REF_COUNT, &pctx)) {
137                         ext2fs_set_ea_inode_ref(EXT2_INODE(inode), actual_refs);
138                         e2fsck_write_inode(ctx, i, EXT2_INODE(inode), "pass4");
139                 }
140         }
141 }
142
143 void e2fsck_pass4(e2fsck_t ctx)
144 {
145         ext2_filsys fs = ctx->fs;
146         ext2_ino_t      i;
147         struct ext2_inode_large *inode;
148         int inode_size = EXT2_INODE_SIZE(fs->super);
149 #ifdef RESOURCE_TRACK
150         struct resource_track   rtrack;
151 #endif
152         struct problem_context  pctx;
153         __u16   link_count, link_counted;
154         int dir_nlink_fs;
155         char    *buf = 0;
156         dgrp_t  group, maxgroup;
157
158         init_resource_track(&rtrack, ctx->fs->io);
159
160 #ifdef MTRACE
161         mtrace_print("Pass 4");
162 #endif
163         /*
164          * Since pass4 is mostly CPU bound, start readahead of bitmaps
165          * ahead of pass 5 if we haven't already loaded them.
166          */
167         if (ctx->readahead_kb &&
168             (fs->block_map == NULL || fs->inode_map == NULL))
169                 e2fsck_readahead(fs, E2FSCK_READA_BBITMAP |
170                                      E2FSCK_READA_IBITMAP,
171                                  0, fs->group_desc_count);
172
173         clear_problem_context(&pctx);
174
175         if (!(ctx->options & E2F_OPT_PREEN))
176                 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
177
178         dir_nlink_fs = ext2fs_has_feature_dir_nlink(fs->super);
179
180         group = 0;
181         maxgroup = fs->group_desc_count;
182         if (ctx->progress)
183                 if ((ctx->progress)(ctx, 4, 0, maxgroup))
184                         return;
185
186         inode = e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
187
188         /* Protect loop from wrap-around if s_inodes_count maxed */
189         for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
190                 ext2_ino_t last_ino = 0;
191                 int isdir;
192
193                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
194                         goto errout;
195                 if ((i % fs->super->s_inodes_per_group) == 0) {
196                         group++;
197                         if (ctx->progress)
198                                 if ((ctx->progress)(ctx, 4, group, maxgroup))
199                                         goto errout;
200                 }
201                 if (i == quota_type2inum(PRJQUOTA, ctx->fs->super) ||
202                     i == fs->super->s_orphan_file_inum || i == EXT2_BAD_INO ||
203                     (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
204                         continue;
205                 if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) ||
206                     (ctx->inode_imagic_map &&
207                      ext2fs_test_inode_bitmap2(ctx->inode_imagic_map, i)) ||
208                     (ctx->inode_bb_map &&
209                      ext2fs_test_inode_bitmap2(ctx->inode_bb_map, i)))
210                         continue;
211                 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
212                 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
213
214                 if (link_counted == 0) {
215                         /*
216                          * link_counted is expected to be 0 for an ea_inode.
217                          * check_ea_inode() will update link_counted if
218                          * necessary.
219                          */
220                         check_ea_inode(ctx, i, &last_ino, inode, &link_counted);
221                 }
222
223                 if (link_counted == 0) {
224                         if (!buf)
225                                 buf = e2fsck_allocate_memory(ctx,
226                                      fs->blocksize, "bad_inode buffer");
227                         if (e2fsck_process_bad_inode(ctx, 0, i, buf))
228                                 continue;
229                         if (disconnect_inode(ctx, i, &last_ino, inode))
230                                 continue;
231                         ext2fs_icount_fetch(ctx->inode_link_info, i,
232                                             &link_count);
233                         ext2fs_icount_fetch(ctx->inode_count, i,
234                                             &link_counted);
235                 }
236                 isdir = ext2fs_test_inode_bitmap2(ctx->inode_dir_map, i);
237                 if (isdir && (link_counted > EXT2_LINK_MAX)) {
238                         if (!dir_nlink_fs &&
239                             fix_problem(ctx, PR_4_DIR_NLINK_FEATURE, &pctx)) {
240                                 ext2fs_set_feature_dir_nlink(fs->super);
241                                 ext2fs_mark_super_dirty(fs);
242                                 dir_nlink_fs = 1;
243                         }
244                         link_counted = 1;
245                 }
246                 if (link_counted != link_count) {
247                         int fix_nlink = 0;
248
249                         if (last_ino != i) {
250                                 e2fsck_read_inode_full(ctx, i,
251                                                        EXT2_INODE(inode),
252                                                        inode_size, "pass4");
253                                 last_ino = i;
254                         }
255                         pctx.ino = i;
256                         pctx.inode = EXT2_INODE(inode);
257                         if ((link_count != inode->i_links_count) && !isdir &&
258                             (inode->i_links_count <= EXT2_LINK_MAX)) {
259                                 pctx.num = link_count;
260                                 fix_problem(ctx,
261                                             PR_4_INCONSISTENT_COUNT, &pctx);
262                         }
263                         pctx.num = link_counted;
264                         /* i_link_count was previously exceeded, but no longer
265                          * is, fix this but don't consider it an error */
266                         if (isdir && link_counted > 1 &&
267                             (inode->i_flags & EXT2_INDEX_FL) &&
268                             link_count == 1) {
269                                 if ((ctx->options & E2F_OPT_READONLY) == 0) {
270                                         fix_nlink =
271                                                 fix_problem(ctx,
272                                                         PR_4_DIR_OVERFLOW_REF_COUNT,
273                                                         &pctx);
274                                 }
275                         } else {
276                                 fix_nlink = fix_problem(ctx, PR_4_BAD_REF_COUNT,
277                                                 &pctx);
278                         }
279                         if (fix_nlink) {
280                                 inode->i_links_count = link_counted;
281                                 e2fsck_write_inode_full(ctx, i,
282                                                         EXT2_INODE(inode),
283                                                         inode_size, "pass4");
284                         }
285                 }
286         }
287         ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
288         ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
289         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
290         ctx->inode_bb_map = 0;
291         ea_refcount_free(ctx->ea_inode_refs);
292         ctx->ea_inode_refs = 0;
293         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
294         ctx->inode_imagic_map = 0;
295 errout:
296         if (buf)
297                 ext2fs_free_mem(&buf);
298
299         ext2fs_free_mem(&inode);
300         print_resource_track(ctx, _("Pass 4"), &rtrack, ctx->fs->io);
301 }
302