]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - e2fsck/pass1.c
Add "make check" to the RPM spec file
[thirdparty/e2fsprogs.git] / e2fsck / pass1.c
CommitLineData
3839e657
TT
1/*
2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
3 *
21c84b71
TT
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%
3839e657
TT
10 *
11 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
12 * and applies the following tests to each inode:
13 *
14 * - The mode field of the inode must be legal.
15 * - The size and block count fields of the inode are correct.
16 * - A data block must not be used by another inode
17 *
18 * Pass 1 also gathers the collects the following information:
19 *
20 * - A bitmap of which inodes are in use. (inode_used_map)
21 * - A bitmap of which inodes are directories. (inode_dir_map)
aa4115a4 22 * - A bitmap of which inodes are regular files. (inode_reg_map)
3839e657 23 * - A bitmap of which inodes have bad fields. (inode_bad_map)
21c84b71 24 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
aa4115a4 25 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
3839e657
TT
26 * - A bitmap of which blocks are in use. (block_found_map)
27 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
28 * - The data blocks of the directory inodes. (dir_map)
29 *
30 * Pass 1 is designed to stash away enough information so that the
31 * other passes should not need to read in the inode information
32 * during the normal course of a filesystem check. (Althogh if an
33 * inconsistency is detected, other passes may need to read in an
34 * inode to fix it.)
35 *
36 * Note that pass 1B will be invoked if there are any duplicate blocks
37 * found.
38 */
39
b969b1b8 40#define _GNU_SOURCE 1 /* get strnlen() */
3e699064 41#include <string.h>
3839e657 42#include <time.h>
50e1e10f
TT
43#ifdef HAVE_ERRNO_H
44#include <errno.h>
45#endif
3839e657 46
3839e657 47#include "e2fsck.h"
342d847d
TT
48#include <ext2fs/ext2_ext_attr.h>
49
21c84b71 50#include "problem.h"
3839e657 51
50e1e10f
TT
52#ifdef NO_INLINE_FUNCS
53#define _INLINE_
54#else
55#define _INLINE_ inline
56#endif
57
3839e657 58static int process_block(ext2_filsys fs, blk_t *blocknr,
9d1bd3de 59 e2_blkcnt_t blockcnt, blk_t ref_blk,
54dc7ca2 60 int ref_offset, void *priv_data);
3839e657 61static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
9d1bd3de 62 e2_blkcnt_t blockcnt, blk_t ref_blk,
54dc7ca2 63 int ref_offset, void *priv_data);
1b6bf175 64static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657 65 char *block_buf);
1b6bf175 66static void mark_table_blocks(e2fsck_t ctx);
1b6bf175 67static void alloc_bb_map(e2fsck_t ctx);
aa4115a4 68static void alloc_imagic_map(e2fsck_t ctx);
fdbdea09 69static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
1b6bf175
TT
70static void handle_fs_bad_blocks(e2fsck_t ctx);
71static void process_inodes(e2fsck_t ctx, char *block_buf);
4c77fe50 72static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
f3db3566 73static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
54dc7ca2 74 dgrp_t group, void * priv_data);
e8a3ee62
TT
75static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
76 char *block_buf, int adjust_sign);
21c84b71 77/* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3839e657
TT
78
79struct process_block_struct {
86c627ec 80 ext2_ino_t ino;
83e692e8 81 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
000ba404 82 fragmented:1, compressed:1, bbcheck:1;
246501c6 83 blk_t num_blocks;
da307041 84 blk_t max_blocks;
9d1bd3de 85 e2_blkcnt_t last_block;
246501c6
TT
86 int num_illegal_blocks;
87 blk_t previous_block;
f3db3566 88 struct ext2_inode *inode;
21c84b71 89 struct problem_context *pctx;
000ba404 90 ext2fs_block_bitmap fs_meta_blocks;
1b6bf175 91 e2fsck_t ctx;
3839e657
TT
92};
93
94struct process_inode_block {
86c627ec 95 ext2_ino_t ino;
3839e657
TT
96 struct ext2_inode inode;
97};
98
f8188fff
TT
99struct scan_callback_struct {
100 e2fsck_t ctx;
101 char *block_buf;
102};
103
3839e657
TT
104/*
105 * For the inodes to process list.
106 */
107static struct process_inode_block *inodes_to_process;
108static int process_inode_count;
3839e657 109
7823dd65
TT
110static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
111 EXT2_MIN_BLOCK_LOG_SIZE + 1];
246501c6 112
f3db3566
TT
113/*
114 * Free all memory allocated by pass1 in preparation for restarting
115 * things.
116 */
54434927 117static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
f3db3566 118{
c4e3d3f3 119 ext2fs_free_mem(&inodes_to_process);
08b21301 120 inodes_to_process = 0;
f3db3566
TT
121}
122
7cf73dcd
TT
123/*
124 * Check to make sure a device inode is real. Returns 1 if the device
125 * checks out, 0 if not.
1dde43f0
TT
126 *
127 * Note: this routine is now also used to check FIFO's and Sockets,
128 * since they have the same requirement; the i_block fields should be
129 * zero.
7cf73dcd 130 */
f954ba01
TT
131int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
132 struct ext2_inode *inode)
7cf73dcd
TT
133{
134 int i;
135
a40ecbb1 136 /*
441ab1e0
TT
137 * If the index flag is set, then this is a bogus
138 * device/fifo/socket
a40ecbb1 139 */
441ab1e0 140 if (inode->i_flags & EXT2_INDEX_FL)
53abed0a 141 return 0;
bcf9c5d4 142
7fdfabd3
TT
143 /*
144 * We should be able to do the test below all the time, but
145 * because the kernel doesn't forcibly clear the device
146 * inode's additional i_block fields, there are some rare
147 * occasions when a legitimate device inode will have non-zero
148 * additional i_block fields. So for now, we only complain
149 * when the immutable flag is set, which should never happen
150 * for devices. (And that's when the problem is caused, since
151 * you can't set or clear immutable flags for devices.) Once
152 * the kernel has been fixed we can change this...
153 */
01fbc701 154 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
7fdfabd3
TT
155 for (i=4; i < EXT2_N_BLOCKS; i++)
156 if (inode->i_block[i])
157 return 0;
158 }
7cf73dcd
TT
159 return 1;
160}
161
67052a8a
AD
162/*
163 * Check to make sure a symlink inode is real. Returns 1 if the symlink
164 * checks out, 0 if not.
165 */
bcf9c5d4
TT
166int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode,
167 char *buf)
67052a8a 168{
54434927 169 unsigned int len;
d007cb4c 170 int i;
0684a4f3 171 blk_t blocks;
67052a8a 172
bcf9c5d4
TT
173 if ((inode->i_size_high || inode->i_size == 0) ||
174 (inode->i_flags & EXT2_INDEX_FL))
67052a8a
AD
175 return 0;
176
0684a4f3
TT
177 blocks = ext2fs_inode_data_blocks(fs, inode);
178 if (blocks) {
b94a052a 179 if ((inode->i_size >= fs->blocksize) ||
0684a4f3 180 (blocks != fs->blocksize >> 9) ||
d007cb4c
TT
181 (inode->i_block[0] < fs->super->s_first_data_block) ||
182 (inode->i_block[0] >= fs->super->s_blocks_count))
67052a8a
AD
183 return 0;
184
185 for (i = 1; i < EXT2_N_BLOCKS; i++)
186 if (inode->i_block[i])
187 return 0;
b94a052a 188
b94a052a
AD
189 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
190 return 0;
191
192 len = strnlen(buf, fs->blocksize);
193 if (len == fs->blocksize)
194 return 0;
67052a8a 195 } else {
b94a052a 196 if (inode->i_size >= sizeof(inode->i_block))
67052a8a
AD
197 return 0;
198
b94a052a
AD
199 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
200 if (len == sizeof(inode->i_block))
67052a8a
AD
201 return 0;
202 }
b94a052a
AD
203 if (len != inode->i_size)
204 return 0;
67052a8a
AD
205 return 1;
206}
207
6fdc7a32 208/*
01fbc701
TT
209 * If the immutable (or append-only) flag is set on the inode, offer
210 * to clear it.
6fdc7a32 211 */
bcf9c5d4 212#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
6fdc7a32
TT
213static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
214{
b94a052a 215 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
6fdc7a32
TT
216 return;
217
218 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
219 return;
220
b94a052a 221 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
6fdc7a32
TT
222 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
223}
224
d647a1ea
TT
225/*
226 * If device, fifo or socket, check size is zero -- if not offer to
227 * clear it
228 */
229static void check_size(e2fsck_t ctx, struct problem_context *pctx)
230{
231 struct ext2_inode *inode = pctx->inode;
232
85645a6f 233 if ((inode->i_size == 0) && (inode->i_size_high == 0))
d647a1ea
TT
234 return;
235
85645a6f 236 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
d647a1ea
TT
237 return;
238
239 inode->i_size = 0;
fdbdea09 240 inode->i_size_high = 0;
d647a1ea
TT
241 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
242}
243
cebe48a1
TT
244static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
245{
246 struct ext2_super_block *sb = ctx->fs->super;
247 struct ext2_inode_large *inode;
248 struct ext2_ext_attr_entry *entry;
642935c0 249 char *start, *end;
1a8c2c4a 250 unsigned int storage_size, remain;
cebe48a1
TT
251 int problem = 0;
252
253 inode = (struct ext2_inode_large *) pctx->inode;
254 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
255 inode->i_extra_isize;
256 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
257 inode->i_extra_isize + sizeof(__u32);
258 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
259 entry = (struct ext2_ext_attr_entry *) start;
260
261 /* scan all entry's headers first */
262
263 /* take finish entry 0UL into account */
264 remain = storage_size - sizeof(__u32);
cebe48a1
TT
265
266 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
267
268 /* header eats this space */
269 remain -= sizeof(struct ext2_ext_attr_entry);
270
271 /* is attribute name valid? */
272 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
273 pctx->num = entry->e_name_len;
274 problem = PR_1_ATTR_NAME_LEN;
275 goto fix;
276 }
277
278 /* attribute len eats this space */
279 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
280
281 /* check value size */
282 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
283 pctx->num = entry->e_value_size;
284 problem = PR_1_ATTR_VALUE_SIZE;
285 goto fix;
286 }
287
cebe48a1
TT
288 /* e_value_block must be 0 in inode's ea */
289 if (entry->e_value_block != 0) {
290 pctx->num = entry->e_value_block;
291 problem = PR_1_ATTR_VALUE_BLOCK;
292 goto fix;
293 }
294
295 /* e_hash must be 0 in inode's ea */
296 if (entry->e_hash != 0) {
297 pctx->num = entry->e_hash;
298 problem = PR_1_ATTR_HASH;
299 goto fix;
300 }
301
302 remain -= entry->e_value_size;
cebe48a1
TT
303
304 entry = EXT2_EXT_ATTR_NEXT(entry);
305 }
306fix:
307 /*
308 * it seems like a corruption. it's very unlikely we could repair
309 * EA(s) in automatic fashion -bzzz
310 */
311#if 0
312 problem = PR_1_ATTR_HASH;
313#endif
314 if (problem == 0 || !fix_problem(ctx, problem, pctx))
315 return;
316
317 /* simple remove all possible EA(s) */
318 *((__u32 *)start) = 0UL;
642935c0 319 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *) inode,
cebe48a1
TT
320 EXT2_INODE_SIZE(sb), "pass1");
321}
322
323static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
324{
325 struct ext2_super_block *sb = ctx->fs->super;
326 struct ext2_inode_large *inode;
327 __u32 *eamagic;
328 int min, max;
329
330 inode = (struct ext2_inode_large *) pctx->inode;
331 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
332 /* this isn't large inode. so, nothing to check */
333 return;
334 }
335
336#if 0
337 printf("inode #%u, i_extra_size %d\n", pctx->ino,
338 inode->i_extra_isize);
339#endif
340 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
341 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
342 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
343 /*
344 * For now we will allow i_extra_isize to be 0, but really
345 * implementations should never allow i_extra_isize to be 0
346 */
347 if (inode->i_extra_isize &&
348 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
349 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
350 return;
351 inode->i_extra_isize = min;
352 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
353 EXT2_INODE_SIZE(sb), "pass1");
354 return;
355 }
356
357 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
358 inode->i_extra_isize);
359 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
360 /* it seems inode has an extended attribute(s) in body */
361 check_ea_in_inode(ctx, pctx);
362 }
363}
6fdc7a32 364
fbc3f901
TT
365/*
366 * Check to see if the inode might really be a directory, despite i_mode
367 *
368 * This is a lot of complexity for something for which I'm not really
369 * convinced happens frequently in the wild. If for any reason this
370 * causes any problems, take this code out.
371 * [tytso:20070331.0827EDT]
372 */
373static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
374 char *buf)
375{
376 struct ext2_inode *inode = pctx->inode;
fbc3f901 377 struct ext2_dir_entry *dirent;
e94bc631
TT
378 const char *old_op;
379 errcode_t retval;
380 blk_t blk;
381 int i, not_device = 0;
fbc3f901
TT
382
383 if (LINUX_S_ISDIR(inode->i_mode) || LINUX_S_ISREG(inode->i_mode) ||
0eeb1549 384 LINUX_S_ISLNK(inode->i_mode) || inode->i_block[0] == 0)
fbc3f901
TT
385 return;
386
0eeb1549 387 for (i=0; i < EXT2_N_BLOCKS; i++) {
fbc3f901
TT
388 blk = inode->i_block[i];
389 if (!blk)
390 continue;
391 if (i >= 4)
392 not_device++;
393
394 if (blk < ctx->fs->super->s_first_data_block ||
395 blk >= ctx->fs->super->s_blocks_count ||
396 ext2fs_fast_test_block_bitmap(ctx->block_found_map, blk))
397 return; /* Invalid block, can't be dir */
398 }
399
400 if ((LINUX_S_ISCHR(inode->i_mode) || LINUX_S_ISBLK(inode->i_mode)) &&
401 (inode->i_links_count == 1) && !not_device)
402 return;
403
e94bc631
TT
404 old_op = ehandler_operation(_("reading directory block"));
405 retval = ext2fs_read_dir_block(ctx->fs, inode->i_block[0], buf);
406 ehandler_operation(0);
407 if (retval)
fbc3f901
TT
408 return;
409
410 dirent = (struct ext2_dir_entry *) buf;
411 if (((dirent->name_len & 0xFF) != 1) ||
412 (dirent->name[0] != '.') ||
413 (dirent->inode != pctx->ino) ||
414 (dirent->rec_len < 12) ||
415 (dirent->rec_len % 4) ||
416 (dirent->rec_len >= ctx->fs->blocksize - 12))
417 return;
418
419 dirent = (struct ext2_dir_entry *) (buf + dirent->rec_len);
420 if (((dirent->name_len & 0xFF) != 2) ||
421 (dirent->name[0] != '.') ||
422 (dirent->name[1] != '.') ||
423 (dirent->rec_len < 12) ||
424 (dirent->rec_len % 4))
425 return;
426
427 if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
428 inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
429 e2fsck_write_inode_full(ctx, pctx->ino, inode,
430 EXT2_INODE_SIZE(ctx->fs->super),
431 "check_is_really_dir");
432 }
433}
434
34b9f796
TT
435extern void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
436 ext2_icount_t *ret)
437{
f954ba01 438 unsigned int threshold;
34b9f796
TT
439 ext2_ino_t num_dirs;
440 errcode_t retval;
f954ba01
TT
441 char *tdb_dir;
442 int enable;
34b9f796
TT
443
444 *ret = 0;
445
446 profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
447 &tdb_dir);
f954ba01
TT
448 profile_get_uint(ctx->profile, "scratch_files",
449 "numdirs_threshold", 0, 0, &threshold);
34b9f796
TT
450 profile_get_boolean(ctx->profile, "scratch_files",
451 "icount", 0, 1, &enable);
452
453 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
454 if (retval)
455 num_dirs = 1024; /* Guess */
456
457 if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
458 (threshold && num_dirs <= threshold))
459 return;
460
461 retval = ext2fs_create_icount_tdb(ctx->fs, tdb_dir, flags, ret);
462 if (retval)
463 *ret = 0;
464}
465
08b21301 466void e2fsck_pass1(e2fsck_t ctx)
3839e657 467{
9d1bd3de 468 int i;
31e29a12 469 __u64 max_sizes;
1b6bf175 470 ext2_filsys fs = ctx->fs;
86c627ec 471 ext2_ino_t ino;
cebe48a1 472 struct ext2_inode *inode;
3839e657
TT
473 ext2_inode_scan scan;
474 char *block_buf;
8bf191e8 475#ifdef RESOURCE_TRACK
3839e657 476 struct resource_track rtrack;
8bf191e8 477#endif
1e3472c5 478 unsigned char frag, fsize;
21c84b71 479 struct problem_context pctx;
f8188fff 480 struct scan_callback_struct scan_struct;
5dd8f963 481 struct ext2_super_block *sb = ctx->fs->super;
e94bc631 482 const char *old_op;
6fdc7a32 483 int imagic_fs;
be93ef0c 484 int busted_fs_time = 0;
cebe48a1 485 int inode_size;
3839e657 486
8bf191e8 487#ifdef RESOURCE_TRACK
3839e657 488 init_resource_track(&rtrack);
8bf191e8 489#endif
1b6bf175
TT
490 clear_problem_context(&pctx);
491
492 if (!(ctx->options & E2F_OPT_PREEN))
493 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3839e657 494
3214a453
TT
495 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
496 !(ctx->options & E2F_OPT_NO)) {
b7a00563
TT
497 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
498 ctx->dirs_to_hash = 0;
499 }
500
3839e657
TT
501#ifdef MTRACE
502 mtrace_print("Pass 1");
503#endif
504
932a489c
AD
505#define EXT2_BPP(bits) (1ULL << ((bits) - 2))
506
507 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
508 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
509 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
510 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
511 max_sizes = (max_sizes * (1UL << i)) - 1;
7823dd65 512 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
9d1bd3de
TT
513 }
514#undef EXT2_BPP
6fdc7a32 515
6fdc7a32
TT
516 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
517
3839e657
TT
518 /*
519 * Allocate bitmaps structures
520 */
0c4a0726 521 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
1b6bf175
TT
522 &ctx->inode_used_map);
523 if (pctx.errcode) {
524 pctx.num = 1;
525 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
526 ctx->flags |= E2F_FLAG_ABORT;
527 return;
3839e657 528 }
0c4a0726
TT
529 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
530 _("directory inode map"), &ctx->inode_dir_map);
1b6bf175
TT
531 if (pctx.errcode) {
532 pctx.num = 2;
533 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
534 ctx->flags |= E2F_FLAG_ABORT;
535 return;
3839e657 536 }
aa4115a4 537 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
0c4a0726 538 _("regular file inode map"), &ctx->inode_reg_map);
aa4115a4
TT
539 if (pctx.errcode) {
540 pctx.num = 6;
541 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
542 ctx->flags |= E2F_FLAG_ABORT;
543 return;
544 }
0c4a0726 545 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
1b6bf175
TT
546 &ctx->block_found_map);
547 if (pctx.errcode) {
548 pctx.num = 1;
549 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
08b21301
TT
550 ctx->flags |= E2F_FLAG_ABORT;
551 return;
3839e657 552 }
34b9f796
TT
553 e2fsck_setup_tdb_icount(ctx, 0, &ctx->inode_link_info);
554 if (!ctx->inode_link_info)
555 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
556 &ctx->inode_link_info);
1b6bf175
TT
557 if (pctx.errcode) {
558 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
08b21301
TT
559 ctx->flags |= E2F_FLAG_ABORT;
560 return;
21c84b71 561 }
cebe48a1
TT
562 inode_size = EXT2_INODE_SIZE(fs->super);
563 inode = (struct ext2_inode *)
564 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
565
54dc7ca2
TT
566 inodes_to_process = (struct process_inode_block *)
567 e2fsck_allocate_memory(ctx,
568 (ctx->process_inode_size *
569 sizeof(struct process_inode_block)),
570 "array of inodes to process");
3839e657
TT
571 process_inode_count = 0;
572
1b6bf175
TT
573 pctx.errcode = ext2fs_init_dblist(fs, 0);
574 if (pctx.errcode) {
575 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
08b21301 576 ctx->flags |= E2F_FLAG_ABORT;
9d45b6ef 577 ext2fs_free_mem(&inode);
08b21301 578 return;
21c84b71 579 }
3839e657 580
9cbfb8d0
TT
581 /*
582 * If the last orphan field is set, clear it, since the pass1
583 * processing will automatically find and clear the orphans.
584 * In the future, we may want to try using the last_orphan
585 * linked list ourselves, but for now, we clear it so that the
586 * ext3 mount code won't get confused.
587 */
588 if (!(ctx->options & E2F_OPT_READONLY)) {
589 if (fs->super->s_last_orphan) {
590 fs->super->s_last_orphan = 0;
591 ext2fs_mark_super_dirty(fs);
592 }
593 }
594
1b6bf175 595 mark_table_blocks(ctx);
54dc7ca2
TT
596 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
597 "block interate buffer");
e72a9ba3 598 e2fsck_use_inode_shortcuts(ctx, 1);
e94bc631 599 old_op = ehandler_operation(_("opening inode scan"));
1b6bf175
TT
600 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
601 &scan);
e94bc631 602 ehandler_operation(old_op);
1b6bf175
TT
603 if (pctx.errcode) {
604 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
08b21301 605 ctx->flags |= E2F_FLAG_ABORT;
9d45b6ef
BB
606 ext2fs_free_mem(&block_buf);
607 ext2fs_free_mem(&inode);
08b21301 608 return;
3839e657 609 }
21c84b71 610 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
cebe48a1 611 ctx->stashed_inode = inode;
f8188fff
TT
612 scan_struct.ctx = ctx;
613 scan_struct.block_buf = block_buf;
614 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
615 if (ctx->progress)
a02ce9df
TT
616 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
617 return;
4147d9f0
TT
618 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
619 (fs->super->s_mtime < fs->super->s_inodes_count))
be93ef0c
TT
620 busted_fs_time = 1;
621
d237a78e 622 while (1) {
e94bc631 623 old_op = ehandler_operation(_("getting next inode from scan"));
cebe48a1
TT
624 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
625 inode, inode_size);
e94bc631 626 ehandler_operation(old_op);
d237a78e
TT
627 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
628 return;
629 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
630 if (!ctx->inode_bb_map)
631 alloc_bb_map(ctx);
632 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
633 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
634 continue;
635 }
636 if (pctx.errcode) {
637 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
638 ctx->flags |= E2F_FLAG_ABORT;
639 return;
640 }
641 if (!ino)
642 break;
21c84b71 643 pctx.ino = ino;
cebe48a1 644 pctx.inode = inode;
1b6bf175 645 ctx->stashed_ino = ino;
cebe48a1 646 if (inode->i_links_count) {
1b6bf175 647 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
cebe48a1 648 ino, inode->i_links_count);
1b6bf175 649 if (pctx.errcode) {
cebe48a1 650 pctx.num = inode->i_links_count;
1b6bf175 651 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
08b21301
TT
652 ctx->flags |= E2F_FLAG_ABORT;
653 return;
1b6bf175
TT
654 }
655 }
3839e657
TT
656 if (ino == EXT2_BAD_INO) {
657 struct process_block_struct pb;
658
000ba404
TT
659 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
660 &pb.fs_meta_blocks);
661 if (pctx.errcode) {
662 pctx.num = 4;
663 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
664 ctx->flags |= E2F_FLAG_ABORT;
665 return;
666 }
3839e657
TT
667 pb.ino = EXT2_BAD_INO;
668 pb.num_blocks = pb.last_block = 0;
f3db3566 669 pb.num_illegal_blocks = 0;
21c84b71 670 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
000ba404 671 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
cebe48a1 672 pb.inode = inode;
21c84b71 673 pb.pctx = &pctx;
1b6bf175
TT
674 pb.ctx = ctx;
675 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
676 block_buf, process_bad_block, &pb);
000ba404 677 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
1b6bf175
TT
678 if (pctx.errcode) {
679 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
08b21301
TT
680 ctx->flags |= E2F_FLAG_ABORT;
681 return;
1b6bf175 682 }
000ba404
TT
683 if (pb.bbcheck)
684 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
685 ctx->flags |= E2F_FLAG_ABORT;
686 return;
687 }
1b6bf175 688 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
21c84b71 689 clear_problem_context(&pctx);
d237a78e 690 continue;
a9ca2016 691 } else if (ino == EXT2_ROOT_INO) {
3839e657
TT
692 /*
693 * Make sure the root inode is a directory; if
694 * not, offer to clear it. It will be
695 * regnerated in pass #3.
696 */
cebe48a1 697 if (!LINUX_S_ISDIR(inode->i_mode)) {
1b6bf175 698 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
1f3ad14a 699 inode->i_dtime = ctx->now;
cebe48a1 700 inode->i_links_count = 0;
1b6bf175 701 ext2fs_icount_store(ctx->inode_link_info,
21c84b71 702 ino, 0);
cebe48a1 703 e2fsck_write_inode(ctx, ino, inode,
f3db3566 704 "pass1");
21c84b71 705 }
b09a4b0c 706
3839e657
TT
707 }
708 /*
709 * If dtime is set, offer to clear it. mke2fs
710 * version 0.2b created filesystems with the
711 * dtime field set for the root and lost+found
712 * directories. We won't worry about
713 * /lost+found, since that can be regenerated
714 * easily. But we will fix the root directory
715 * as a special case.
716 */
cebe48a1 717 if (inode->i_dtime && inode->i_links_count) {
1b6bf175 718 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
cebe48a1
TT
719 inode->i_dtime = 0;
720 e2fsck_write_inode(ctx, ino, inode,
f3db3566 721 "pass1");
21c84b71 722 }
3839e657 723 }
a9ca2016 724 } else if (ino == EXT2_JOURNAL_INO) {
f18996c8
TT
725 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
726 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
cebe48a1 727 if (!LINUX_S_ISREG(inode->i_mode) &&
a9ca2016
TT
728 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
729 &pctx)) {
cebe48a1
TT
730 inode->i_mode = LINUX_S_IFREG;
731 e2fsck_write_inode(ctx, ino, inode,
a9ca2016
TT
732 "pass1");
733 }
f18996c8 734 check_blocks(ctx, &pctx, block_buf);
d237a78e 735 continue;
f18996c8 736 }
cebe48a1
TT
737 if ((inode->i_links_count || inode->i_blocks ||
738 inode->i_blocks || inode->i_block[0]) &&
a9ca2016 739 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
f18996c8 740 &pctx)) {
cebe48a1 741 memset(inode, 0, inode_size);
a9ca2016
TT
742 ext2fs_icount_store(ctx->inode_link_info,
743 ino, 0);
cebe48a1
TT
744 e2fsck_write_inode_full(ctx, ino, inode,
745 inode_size, "pass1");
f18996c8 746 }
a9ca2016 747 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
b09a4b0c
TT
748 int problem = 0;
749
1b6bf175 750 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
53ef44c4 751 if (ino == EXT2_BOOT_LOADER_INO) {
cebe48a1 752 if (LINUX_S_ISDIR(inode->i_mode))
b09a4b0c 753 problem = PR_1_RESERVED_BAD_MODE;
b1f204f7 754 } else if (ino == EXT2_RESIZE_INO) {
cebe48a1
TT
755 if (inode->i_mode &&
756 !LINUX_S_ISREG(inode->i_mode))
b1f204f7 757 problem = PR_1_RESERVED_BAD_MODE;
53ef44c4 758 } else {
cebe48a1 759 if (inode->i_mode != 0)
b09a4b0c 760 problem = PR_1_RESERVED_BAD_MODE;
b09a4b0c
TT
761 }
762 if (problem) {
763 if (fix_problem(ctx, problem, &pctx)) {
cebe48a1
TT
764 inode->i_mode = 0;
765 e2fsck_write_inode(ctx, ino, inode,
50e1e10f 766 "pass1");
21c84b71 767 }
50e1e10f 768 }
1b6bf175 769 check_blocks(ctx, &pctx, block_buf);
d237a78e 770 continue;
3839e657 771 }
21afac09
TT
772 /*
773 * Check for inodes who might have been part of the
774 * orphaned list linked list. They should have gotten
775 * dealt with by now, unless the list had somehow been
776 * corrupted.
777 *
778 * FIXME: In the future, inodes which are still in use
779 * (and which are therefore) pending truncation should
780 * be handled specially. Right now we just clear the
781 * dtime field, and the normal e2fsck handling of
782 * inodes where i_size and the inode blocks are
783 * inconsistent is to fix i_size, instead of releasing
784 * the extra blocks. This won't catch the inodes that
785 * was at the end of the orphan list, but it's better
786 * than nothing. The right answer is that there
787 * shouldn't be any bugs in the orphan list handling. :-)
788 */
cebe48a1
TT
789 if (inode->i_dtime && !busted_fs_time &&
790 inode->i_dtime < ctx->fs->super->s_inodes_count) {
21afac09 791 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
cebe48a1 792 inode->i_dtime = inode->i_links_count ?
1f3ad14a 793 0 : ctx->now;
cebe48a1 794 e2fsck_write_inode(ctx, ino, inode,
21afac09
TT
795 "pass1");
796 }
797 }
798
3839e657
TT
799 /*
800 * This code assumes that deleted inodes have
801 * i_links_count set to 0.
802 */
cebe48a1
TT
803 if (!inode->i_links_count) {
804 if (!inode->i_dtime && inode->i_mode) {
1b6bf175 805 if (fix_problem(ctx,
21c84b71 806 PR_1_ZERO_DTIME, &pctx)) {
1f3ad14a 807 inode->i_dtime = ctx->now;
cebe48a1 808 e2fsck_write_inode(ctx, ino, inode,
f3db3566 809 "pass1");
21c84b71 810 }
3839e657 811 }
d237a78e 812 continue;
3839e657
TT
813 }
814 /*
1e3472c5 815 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3839e657 816 * deleted files. Oops.
1e3472c5
TT
817 *
818 * Since all new ext2 implementations get this right,
819 * we now assume that the case of non-zero
820 * i_links_count and non-zero dtime means that we
821 * should keep the file, not delete it.
3839e657 822 *
3839e657 823 */
cebe48a1 824 if (inode->i_dtime) {
1b6bf175 825 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
cebe48a1
TT
826 inode->i_dtime = 0;
827 e2fsck_write_inode(ctx, ino, inode, "pass1");
21c84b71 828 }
3839e657
TT
829 }
830
1b6bf175 831 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
1e3472c5 832 switch (fs->super->s_creator_os) {
1e3472c5 833 case EXT2_OS_HURD:
cebe48a1
TT
834 frag = inode->osd2.hurd2.h_i_frag;
835 fsize = inode->osd2.hurd2.h_i_fsize;
1e3472c5
TT
836 break;
837 case EXT2_OS_MASIX:
cebe48a1
TT
838 frag = inode->osd2.masix2.m_i_frag;
839 fsize = inode->osd2.masix2.m_i_fsize;
1e3472c5
TT
840 break;
841 default:
842 frag = fsize = 0;
843 }
844
cebe48a1
TT
845 if (inode->i_faddr || frag || fsize ||
846 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
fdbdea09 847 mark_inode_bad(ctx, ino);
5d17119d
TT
848 if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
849 !(fs->super->s_feature_ro_compat &
850 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
851 (inode->osd2.linux2.l_i_blocks_hi != 0))
852 mark_inode_bad(ctx, ino);
cebe48a1 853 if (inode->i_flags & EXT2_IMAGIC_FL) {
6fdc7a32
TT
854 if (imagic_fs) {
855 if (!ctx->inode_imagic_map)
856 alloc_imagic_map(ctx);
857 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
858 ino);
859 } else {
860 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
cebe48a1 861 inode->i_flags &= ~EXT2_IMAGIC_FL;
6fdc7a32 862 e2fsck_write_inode(ctx, ino,
cebe48a1 863 inode, "pass1");
6fdc7a32
TT
864 }
865 }
aa4115a4 866 }
cebe48a1
TT
867
868 check_inode_extra_space(ctx, &pctx);
fbc3f901 869 check_is_really_dir(ctx, &pctx, block_buf);
cebe48a1
TT
870
871 if (LINUX_S_ISDIR(inode->i_mode)) {
1b6bf175 872 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
08b21301 873 e2fsck_add_dir_info(ctx, ino, 0);
1b6bf175 874 ctx->fs_directory_count++;
cebe48a1 875 } else if (LINUX_S_ISREG (inode->i_mode)) {
aa4115a4 876 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
1b6bf175 877 ctx->fs_regular_count++;
cebe48a1
TT
878 } else if (LINUX_S_ISCHR (inode->i_mode) &&
879 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 880 check_immutable(ctx, &pctx);
d647a1ea 881 check_size(ctx, &pctx);
1b6bf175 882 ctx->fs_chardev_count++;
cebe48a1
TT
883 } else if (LINUX_S_ISBLK (inode->i_mode) &&
884 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 885 check_immutable(ctx, &pctx);
d647a1ea 886 check_size(ctx, &pctx);
1b6bf175 887 ctx->fs_blockdev_count++;
cebe48a1
TT
888 } else if (LINUX_S_ISLNK (inode->i_mode) &&
889 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
fd77b2c7 890 check_immutable(ctx, &pctx);
1b6bf175 891 ctx->fs_symlinks_count++;
cebe48a1 892 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
1b6bf175 893 ctx->fs_fast_symlinks_count++;
0684a4f3 894 check_blocks(ctx, &pctx, block_buf);
d237a78e 895 continue;
21c84b71 896 }
3839e657 897 }
cebe48a1
TT
898 else if (LINUX_S_ISFIFO (inode->i_mode) &&
899 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 900 check_immutable(ctx, &pctx);
d647a1ea 901 check_size(ctx, &pctx);
1b6bf175 902 ctx->fs_fifo_count++;
cebe48a1
TT
903 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
904 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 905 check_immutable(ctx, &pctx);
d647a1ea
TT
906 check_size(ctx, &pctx);
907 ctx->fs_sockets_count++;
fdbdea09
TT
908 } else
909 mark_inode_bad(ctx, ino);
cebe48a1 910 if (inode->i_block[EXT2_IND_BLOCK])
1b6bf175 911 ctx->fs_ind_count++;
cebe48a1 912 if (inode->i_block[EXT2_DIND_BLOCK])
1b6bf175 913 ctx->fs_dind_count++;
cebe48a1 914 if (inode->i_block[EXT2_TIND_BLOCK])
1b6bf175 915 ctx->fs_tind_count++;
cebe48a1
TT
916 if (inode->i_block[EXT2_IND_BLOCK] ||
917 inode->i_block[EXT2_DIND_BLOCK] ||
918 inode->i_block[EXT2_TIND_BLOCK] ||
919 inode->i_file_acl) {
3839e657 920 inodes_to_process[process_inode_count].ino = ino;
cebe48a1 921 inodes_to_process[process_inode_count].inode = *inode;
3839e657 922 process_inode_count++;
f3db3566 923 } else
1b6bf175 924 check_blocks(ctx, &pctx, block_buf);
3839e657 925
a02ce9df 926 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
927 return;
928
929 if (process_inode_count >= ctx->process_inode_size) {
1b6bf175 930 process_inodes(ctx, block_buf);
08b21301 931
a02ce9df 932 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
933 return;
934 }
3839e657 935 }
1b6bf175 936 process_inodes(ctx, block_buf);
3839e657 937 ext2fs_close_inode_scan(scan);
3839e657 938
e8a3ee62
TT
939 /*
940 * If any extended attribute blocks' reference counts need to
941 * be adjusted, either up (ctx->refcount_extra), or down
942 * (ctx->refcount), then fix them.
943 */
944 if (ctx->refcount) {
945 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
946 ea_refcount_free(ctx->refcount);
947 ctx->refcount = 0;
948 }
949 if (ctx->refcount_extra) {
950 adjust_extattr_refcount(ctx, ctx->refcount_extra,
951 block_buf, +1);
952 ea_refcount_free(ctx->refcount_extra);
953 ctx->refcount_extra = 0;
954 }
955
1b6bf175
TT
956 if (ctx->invalid_bitmaps)
957 handle_fs_bad_blocks(ctx);
f3db3566 958
24ceb248
TT
959 /* We don't need the block_ea_map any more */
960 if (ctx->block_ea_map) {
961 ext2fs_free_block_bitmap(ctx->block_ea_map);
962 ctx->block_ea_map = 0;
963 }
964
c3ffaf83
TT
965 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
966 ext2fs_block_bitmap save_bmap;
c3ffaf83
TT
967
968 save_bmap = fs->block_map;
969 fs->block_map = ctx->block_found_map;
970 clear_problem_context(&pctx);
971 pctx.errcode = ext2fs_create_resize_inode(fs);
972 if (pctx.errcode) {
973 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
974 /* Should never get here */
975 ctx->flags |= E2F_FLAG_ABORT;
976 return;
977 }
1f3ad14a
TT
978 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
979 "recreate inode");
980 inode->i_mtime = ctx->now;
981 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
982 "recreate inode");
c3ffaf83
TT
983 fs->block_map = save_bmap;
984 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
985 }
986
08b21301 987 if (ctx->flags & E2F_FLAG_RESTART) {
aa4115a4
TT
988 /*
989 * Only the master copy of the superblock and block
990 * group descriptors are going to be written during a
991 * restart, so set the superblock to be used to be the
992 * master superblock.
993 */
994 ctx->use_superblock = 0;
f3db3566
TT
995 unwind_pass1(fs);
996 goto endit;
997 }
998
1b6bf175
TT
999 if (ctx->block_dup_map) {
1000 if (ctx->options & E2F_OPT_PREEN) {
1001 clear_problem_context(&pctx);
1002 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3839e657 1003 }
08b21301 1004 e2fsck_pass1_dupblocks(ctx, block_buf);
3839e657 1005 }
c4e3d3f3 1006 ext2fs_free_mem(&inodes_to_process);
f3db3566 1007endit:
e72a9ba3 1008 e2fsck_use_inode_shortcuts(ctx, 0);
1e3472c5 1009
c4e3d3f3 1010 ext2fs_free_mem(&block_buf);
cebe48a1 1011 ext2fs_free_mem(&inode);
21c84b71 1012
8bf191e8 1013#ifdef RESOURCE_TRACK
5596defa
TT
1014 if (ctx->options & E2F_OPT_TIME2) {
1015 e2fsck_clear_progbar(ctx);
0c4a0726 1016 print_resource_track(_("Pass 1"), &rtrack);
5596defa 1017 }
8bf191e8 1018#endif
3839e657
TT
1019}
1020
f3db3566
TT
1021/*
1022 * When the inode_scan routines call this callback at the end of the
1023 * glock group, call process_inodes.
1024 */
54434927
TT
1025static errcode_t scan_callback(ext2_filsys fs,
1026 ext2_inode_scan scan EXT2FS_ATTR((unused)),
54dc7ca2 1027 dgrp_t group, void * priv_data)
f3db3566 1028{
54dc7ca2 1029 struct scan_callback_struct *scan_struct;
f8188fff
TT
1030 e2fsck_t ctx;
1031
54dc7ca2 1032 scan_struct = (struct scan_callback_struct *) priv_data;
f8188fff
TT
1033 ctx = scan_struct->ctx;
1034
54dc7ca2 1035 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
f8188fff
TT
1036
1037 if (ctx->progress)
a02ce9df
TT
1038 if ((ctx->progress)(ctx, 1, group+1,
1039 ctx->fs->group_desc_count))
1040 return EXT2_ET_CANCEL_REQUESTED;
f8188fff 1041
f3db3566
TT
1042 return 0;
1043}
1044
3839e657
TT
1045/*
1046 * Process the inodes in the "inodes to process" list.
1047 */
1b6bf175 1048static void process_inodes(e2fsck_t ctx, char *block_buf)
3839e657
TT
1049{
1050 int i;
1051 struct ext2_inode *old_stashed_inode;
86c627ec 1052 ext2_ino_t old_stashed_ino;
3839e657
TT
1053 const char *old_operation;
1054 char buf[80];
21c84b71
TT
1055 struct problem_context pctx;
1056
3839e657 1057#if 0
f3db3566 1058 printf("begin process_inodes: ");
3839e657 1059#endif
86a63e92
TT
1060 if (process_inode_count == 0)
1061 return;
3839e657 1062 old_operation = ehandler_operation(0);
1b6bf175
TT
1063 old_stashed_inode = ctx->stashed_inode;
1064 old_stashed_ino = ctx->stashed_ino;
3839e657
TT
1065 qsort(inodes_to_process, process_inode_count,
1066 sizeof(struct process_inode_block), process_inode_cmp);
21c84b71 1067 clear_problem_context(&pctx);
3839e657 1068 for (i=0; i < process_inode_count; i++) {
1b6bf175
TT
1069 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
1070 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
21c84b71 1071
3839e657 1072#if 0
21c84b71 1073 printf("%u ", pctx.ino);
3839e657 1074#endif
86c627ec 1075 sprintf(buf, _("reading indirect blocks of inode %u"),
0c4a0726 1076 pctx.ino);
3839e657 1077 ehandler_operation(buf);
1b6bf175 1078 check_blocks(ctx, &pctx, block_buf);
a02ce9df 1079 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2df1f6aa 1080 break;
3839e657 1081 }
1b6bf175
TT
1082 ctx->stashed_inode = old_stashed_inode;
1083 ctx->stashed_ino = old_stashed_ino;
3839e657
TT
1084 process_inode_count = 0;
1085#if 0
f3db3566 1086 printf("end process inodes\n");
3839e657
TT
1087#endif
1088 ehandler_operation(old_operation);
1089}
1090
4c77fe50 1091static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
3839e657
TT
1092{
1093 const struct process_inode_block *ib_a =
1094 (const struct process_inode_block *) a;
1095 const struct process_inode_block *ib_b =
1096 (const struct process_inode_block *) b;
b5acdb6a
TT
1097 int ret;
1098
1099 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
1100 ib_b->inode.i_block[EXT2_IND_BLOCK]);
1101 if (ret == 0)
1102 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
1103 return ret;
3839e657
TT
1104}
1105
3839e657 1106/*
fdbdea09 1107 * Mark an inode as being bad in some what
3839e657 1108 */
fdbdea09 1109static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3839e657 1110{
1b6bf175 1111 struct problem_context pctx;
fdbdea09
TT
1112
1113 if (!ctx->inode_bad_map) {
1114 clear_problem_context(&pctx);
1b6bf175 1115
fdbdea09
TT
1116 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1117 _("bad inode map"), &ctx->inode_bad_map);
1118 if (pctx.errcode) {
1119 pctx.num = 3;
1120 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1121 /* Should never get here */
1122 ctx->flags |= E2F_FLAG_ABORT;
1123 return;
1124 }
3839e657 1125 }
fdbdea09 1126 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3839e657
TT
1127}
1128
fdbdea09 1129
21c84b71
TT
1130/*
1131 * This procedure will allocate the inode "bb" (badblock) map table
1132 */
1b6bf175 1133static void alloc_bb_map(e2fsck_t ctx)
21c84b71 1134{
1b6bf175 1135 struct problem_context pctx;
21c84b71 1136
1b6bf175
TT
1137 clear_problem_context(&pctx);
1138 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
0c4a0726 1139 _("inode in bad block map"),
1b6bf175
TT
1140 &ctx->inode_bb_map);
1141 if (pctx.errcode) {
1142 pctx.num = 4;
1143 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
1144 /* Should never get here */
1145 ctx->flags |= E2F_FLAG_ABORT;
1146 return;
21c84b71
TT
1147 }
1148}
1149
aa4115a4
TT
1150/*
1151 * This procedure will allocate the inode imagic table
1152 */
1153static void alloc_imagic_map(e2fsck_t ctx)
1154{
1155 struct problem_context pctx;
1156
1157 clear_problem_context(&pctx);
1158 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
0c4a0726 1159 _("imagic inode map"),
aa4115a4
TT
1160 &ctx->inode_imagic_map);
1161 if (pctx.errcode) {
1162 pctx.num = 5;
1163 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1164 /* Should never get here */
1165 ctx->flags |= E2F_FLAG_ABORT;
1166 return;
1167 }
1168}
1169
3839e657
TT
1170/*
1171 * Marks a block as in use, setting the dup_map if it's been set
1172 * already. Called by process_block and process_bad_block.
50e1e10f
TT
1173 *
1174 * WARNING: Assumes checks have already been done to make sure block
1175 * is valid. This is true in both process_block and process_bad_block.
3839e657 1176 */
1b6bf175 1177static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
3839e657 1178{
1b6bf175
TT
1179 struct problem_context pctx;
1180
1181 clear_problem_context(&pctx);
3839e657 1182
1b6bf175
TT
1183 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
1184 if (!ctx->block_dup_map) {
1185 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
0c4a0726 1186 _("multiply claimed block map"),
1b6bf175
TT
1187 &ctx->block_dup_map);
1188 if (pctx.errcode) {
1189 pctx.num = 3;
1190 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
1191 &pctx);
08b21301
TT
1192 /* Should never get here */
1193 ctx->flags |= E2F_FLAG_ABORT;
1194 return;
3839e657
TT
1195 }
1196 }
1b6bf175 1197 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3839e657 1198 } else {
1b6bf175 1199 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3839e657
TT
1200 }
1201}
1202
e8a3ee62
TT
1203/*
1204 * Adjust the extended attribute block's reference counts at the end
1205 * of pass 1, either by subtracting out references for EA blocks that
1206 * are still referenced in ctx->refcount, or by adding references for
1207 * EA blocks that had extra references as accounted for in
1208 * ctx->refcount_extra.
1209 */
1210static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
1211 char *block_buf, int adjust_sign)
1212{
1213 struct ext2_ext_attr_header *header;
1214 struct problem_context pctx;
1215 ext2_filsys fs = ctx->fs;
e8a3ee62
TT
1216 blk_t blk;
1217 __u32 should_be;
1218 int count;
1219
1220 clear_problem_context(&pctx);
1221
1222 ea_refcount_intr_begin(refcount);
1223 while (1) {
1224 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
1225 break;
1226 pctx.blk = blk;
1227 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1228 if (pctx.errcode) {
1229 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
1230 return;
1231 }
1232 header = (struct ext2_ext_attr_header *) block_buf;
1233 pctx.blkcount = header->h_refcount;
1234 should_be = header->h_refcount + adjust_sign * count;
1235 pctx.num = should_be;
1236 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
1237 header->h_refcount = should_be;
1238 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
1239 block_buf);
1240 if (pctx.errcode) {
1241 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
1242 continue;
1243 }
1244 }
1245 }
1246}
1247
342d847d
TT
1248/*
1249 * Handle processing the extended attribute blocks
1250 */
1251static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
1252 char *block_buf)
1253{
1254 ext2_filsys fs = ctx->fs;
1255 ext2_ino_t ino = pctx->ino;
1256 struct ext2_inode *inode = pctx->inode;
1257 blk_t blk;
55fd07ed 1258 char * end;
e8a3ee62 1259 struct ext2_ext_attr_header *header;
55fd07ed 1260 struct ext2_ext_attr_entry *entry;
342d847d 1261 int count;
86bc90f4 1262 region_t region = 0;
5469d767 1263
342d847d
TT
1264 blk = inode->i_file_acl;
1265 if (blk == 0)
1266 return 0;
1267
1268 /*
1269 * If the Extended attribute flag isn't set, then a non-zero
1270 * file acl means that the inode is corrupted.
1271 *
1272 * Or if the extended attribute block is an invalid block,
1273 * then the inode is also corrupted.
1274 */
1275 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
1276 (blk < fs->super->s_first_data_block) ||
1277 (blk >= fs->super->s_blocks_count)) {
1278 mark_inode_bad(ctx, ino);
1279 return 0;
1280 }
1281
1282 /* If ea bitmap hasn't been allocated, create it */
1283 if (!ctx->block_ea_map) {
1284 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
1285 _("ext attr block map"),
1286 &ctx->block_ea_map);
1287 if (pctx->errcode) {
1288 pctx->num = 2;
1289 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
1290 ctx->flags |= E2F_FLAG_ABORT;
1291 return 0;
1292 }
1293 }
1294
1295 /* Create the EA refcount structure if necessary */
1296 if (!ctx->refcount) {
1297 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
1298 if (pctx->errcode) {
1299 pctx->num = 1;
1300 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1301 ctx->flags |= E2F_FLAG_ABORT;
1302 return 0;
1303 }
1304 }
1305
b5acdb6a
TT
1306#if 0
1307 /* Debugging text */
1308 printf("Inode %u has EA block %u\n", ino, blk);
1309#endif
1310
342d847d
TT
1311 /* Have we seen this EA block before? */
1312 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
1313 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
1314 return 1;
1315 /* Ooops, this EA was referenced more than it stated */
1316 if (!ctx->refcount_extra) {
1317 pctx->errcode = ea_refcount_create(0,
1318 &ctx->refcount_extra);
1319 if (pctx->errcode) {
1320 pctx->num = 2;
1321 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1322 ctx->flags |= E2F_FLAG_ABORT;
55fd07ed 1323 return 0;
342d847d
TT
1324 }
1325 }
1326 ea_refcount_increment(ctx->refcount_extra, blk, 0);
1327 return 1;
1328 }
5469d767 1329
342d847d
TT
1330 /*
1331 * OK, we haven't seen this EA block yet. So we need to
1332 * validate it
1333 */
1334 pctx->blk = blk;
1335 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1336 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
1337 goto clear_extattr;
342d847d 1338 header = (struct ext2_ext_attr_header *) block_buf;
55fd07ed 1339 pctx->blk = inode->i_file_acl;
0684a4f3
TT
1340 if (((ctx->ext_attr_ver == 1) &&
1341 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
1342 ((ctx->ext_attr_ver == 2) &&
1343 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
1344 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
1345 goto clear_extattr;
1346 }
0d63467d 1347
55fd07ed
TT
1348 if (header->h_blocks != 1) {
1349 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
1350 goto clear_extattr;
1351 }
1352
1353 region = region_create(0, fs->blocksize);
1354 if (!region) {
1355 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
1356 ctx->flags |= E2F_FLAG_ABORT;
1357 return 0;
1358 }
1359 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
1360 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
342d847d
TT
1361 goto clear_extattr;
1362 }
5469d767 1363
55fd07ed
TT
1364 entry = (struct ext2_ext_attr_entry *)(header+1);
1365 end = block_buf + fs->blocksize;
1366 while ((char *)entry < end && *(__u32 *)entry) {
1367 if (region_allocate(region, (char *)entry - (char *)header,
1368 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
1369 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1370 goto clear_extattr;
1371 }
0684a4f3 1372 if ((ctx->ext_attr_ver == 1 &&
0d63467d 1373 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
0684a4f3 1374 (ctx->ext_attr_ver == 2 &&
0d63467d 1375 entry->e_name_index == 0)) {
55fd07ed
TT
1376 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
1377 goto clear_extattr;
1378 }
1379 if (entry->e_value_block != 0) {
1380 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1381 goto clear_extattr;
1382 }
a34c6ffd
AD
1383 if (entry->e_value_offs + entry->e_value_size > fs->blocksize) {
1384 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1385 goto clear_extattr;
1386 break;
1387 }
14fe1c33
TT
1388 if (entry->e_value_size &&
1389 region_allocate(region, entry->e_value_offs,
1390 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
55fd07ed
TT
1391 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1392 goto clear_extattr;
1393 }
1394 entry = EXT2_EXT_ATTR_NEXT(entry);
1395 }
1396 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
1397 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1398 goto clear_extattr;
1399 }
1400 region_free(region);
342d847d
TT
1401
1402 count = header->h_refcount - 1;
1403 if (count)
1404 ea_refcount_store(ctx->refcount, blk, count);
1405 mark_block_used(ctx, blk);
1406 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
342d847d
TT
1407 return 1;
1408
1409clear_extattr:
5469d767
BB
1410 if (region)
1411 region_free(region);
342d847d
TT
1412 inode->i_file_acl = 0;
1413 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
1414 return 0;
1415}
1416
503f9e7f
TT
1417/* Returns 1 if bad htree, 0 if OK */
1418static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
54434927
TT
1419 ext2_ino_t ino EXT2FS_ATTR((unused)),
1420 struct ext2_inode *inode,
503f9e7f
TT
1421 char *block_buf)
1422{
1423 struct ext2_dx_root_info *root;
1424 ext2_filsys fs = ctx->fs;
1425 errcode_t retval;
1426 blk_t blk;
1427
1428 if ((!LINUX_S_ISDIR(inode->i_mode) &&
1429 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
1430 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
1431 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
1432 return 1;
1433
1434 blk = inode->i_block[0];
1435 if (((blk == 0) ||
1436 (blk < fs->super->s_first_data_block) ||
1437 (blk >= fs->super->s_blocks_count)) &&
1438 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1439 return 1;
1440
1441 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
1442 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1443 return 1;
1444
1445 /* XXX should check that beginning matches a directory */
1446 root = (struct ext2_dx_root_info *) (block_buf + 24);
1447
1448 if ((root->reserved_zero || root->info_length < 8) &&
1449 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1450 return 1;
1451
1452 pctx->num = root->hash_version;
1453 if ((root->hash_version != EXT2_HASH_LEGACY) &&
1454 (root->hash_version != EXT2_HASH_HALF_MD4) &&
f044b4d8 1455 (root->hash_version != EXT2_HASH_TEA) &&
503f9e7f
TT
1456 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
1457 return 1;
1458
1459 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
1460 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
1461 return 1;
1462
1463 pctx->num = root->indirect_levels;
1464 if ((root->indirect_levels > 1) &&
1465 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
1466 return 1;
1467
1468 return 0;
1469}
342d847d 1470
3839e657
TT
1471/*
1472 * This subroutine is called on each inode to account for all of the
1473 * blocks used by that inode.
1474 */
1b6bf175 1475static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657
TT
1476 char *block_buf)
1477{
1b6bf175 1478 ext2_filsys fs = ctx->fs;
3839e657 1479 struct process_block_struct pb;
86c627ec 1480 ext2_ino_t ino = pctx->ino;
21c84b71 1481 struct ext2_inode *inode = pctx->inode;
246501c6 1482 int bad_size = 0;
503f9e7f 1483 int dirty_inode = 0;
246501c6 1484 __u64 size;
3839e657 1485
3839e657 1486 pb.ino = ino;
0684a4f3
TT
1487 pb.num_blocks = 0;
1488 pb.last_block = -1;
f3db3566 1489 pb.num_illegal_blocks = 0;
21c84b71 1490 pb.suppress = 0; pb.clear = 0;
74becf3c 1491 pb.fragmented = 0;
1917875f 1492 pb.compressed = 0;
74becf3c 1493 pb.previous_block = 0;
b94a052a 1494 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
da307041
TT
1495 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
1496 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
f3db3566 1497 pb.inode = inode;
21c84b71 1498 pb.pctx = pctx;
1b6bf175
TT
1499 pb.ctx = ctx;
1500 pctx->ino = ino;
0684a4f3 1501 pctx->errcode = 0;
1917875f
TT
1502
1503 if (inode->i_flags & EXT2_COMPRBLK_FL) {
f5ae75e5
TT
1504 if (fs->super->s_feature_incompat &
1505 EXT2_FEATURE_INCOMPAT_COMPRESSION)
1917875f
TT
1506 pb.compressed = 1;
1507 else {
1508 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
1509 inode->i_flags &= ~EXT2_COMPRBLK_FL;
503f9e7f 1510 dirty_inode++;
1917875f
TT
1511 }
1512 }
1513 }
1514
dc71f23e
TT
1515 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
1516 pb.num_blocks++;
1517
0684a4f3
TT
1518 if (ext2fs_inode_has_valid_blocks(inode))
1519 pctx->errcode = ext2fs_block_iterate2(fs, ino,
21c84b71
TT
1520 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
1521 block_buf, process_block, &pb);
1b6bf175 1522 end_problem_latch(ctx, PR_LATCH_BLOCK);
da307041 1523 end_problem_latch(ctx, PR_LATCH_TOOBIG);
0684a4f3
TT
1524 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1525 goto out;
1b6bf175
TT
1526 if (pctx->errcode)
1527 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
3839e657 1528
74becf3c 1529 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
1b6bf175 1530 ctx->fs_fragmented++;
74becf3c 1531
f3db3566 1532 if (pb.clear) {
f3db3566 1533 inode->i_links_count = 0;
1b6bf175 1534 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
1f3ad14a 1535 inode->i_dtime = ctx->now;
503f9e7f 1536 dirty_inode++;
1b6bf175 1537 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
aa4115a4 1538 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
1b6bf175 1539 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
f3db3566
TT
1540 /*
1541 * The inode was probably partially accounted for
1542 * before processing was aborted, so we need to
1543 * restart the pass 1 scan.
1544 */
08b21301 1545 ctx->flags |= E2F_FLAG_RESTART;
503f9e7f 1546 goto out;
f3db3566 1547 }
8fdc9985
TT
1548
1549 if (inode->i_flags & EXT2_INDEX_FL) {
503f9e7f
TT
1550 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
1551 inode->i_flags &= ~EXT2_INDEX_FL;
1552 dirty_inode++;
1553 } else {
8fdc9985
TT
1554#ifdef ENABLE_HTREE
1555 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
1556#endif
503f9e7f 1557 }
8fdc9985 1558 }
b7a00563
TT
1559 if (ctx->dirs_to_hash && pb.is_dir &&
1560 !(inode->i_flags & EXT2_INDEX_FL) &&
1561 ((inode->i_size / fs->blocksize) >= 3))
1562 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
1563
3839e657 1564 if (!pb.num_blocks && pb.is_dir) {
1b6bf175 1565 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
3839e657 1566 inode->i_links_count = 0;
1b6bf175 1567 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
1f3ad14a 1568 inode->i_dtime = ctx->now;
503f9e7f 1569 dirty_inode++;
1b6bf175 1570 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
aa4115a4 1571 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
1b6bf175
TT
1572 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
1573 ctx->fs_directory_count--;
0684a4f3 1574 goto out;
21c84b71 1575 }
3839e657 1576 }
0684a4f3 1577
0684a4f3
TT
1578 pb.num_blocks *= (fs->blocksize / 512);
1579#if 0
1580 printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
1581 ino, inode->i_size, pb.last_block, inode->i_blocks,
1582 pb.num_blocks);
1583#endif
246501c6
TT
1584 if (pb.is_dir) {
1585 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
da307041 1586 if (nblock > (pb.last_block + 1))
246501c6
TT
1587 bad_size = 1;
1588 else if (nblock < (pb.last_block + 1)) {
246501c6 1589 if (((pb.last_block + 1) - nblock) >
5dd8f963 1590 fs->super->s_prealloc_dir_blocks)
9d1bd3de 1591 bad_size = 2;
246501c6
TT
1592 }
1593 } else {
4f489285 1594 size = EXT2_I_SIZE(inode);
0684a4f3 1595 if ((pb.last_block >= 0) &&
54434927 1596 (size < (__u64) pb.last_block * fs->blocksize))
9d1bd3de 1597 bad_size = 3;
246501c6 1598 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
9d1bd3de 1599 bad_size = 4;
246501c6 1600 }
0684a4f3
TT
1601 /* i_size for symlinks is checked elsewhere */
1602 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
21c84b71 1603 pctx->num = (pb.last_block+1) * fs->blocksize;
1b6bf175 1604 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
21c84b71 1605 inode->i_size = pctx->num;
0684a4f3 1606 if (!LINUX_S_ISDIR(inode->i_mode))
246501c6 1607 inode->i_size_high = pctx->num >> 32;
503f9e7f 1608 dirty_inode++;
21c84b71
TT
1609 }
1610 pctx->num = 0;
3839e657 1611 }
b94a052a
AD
1612 if (LINUX_S_ISREG(inode->i_mode) &&
1613 (inode->i_size_high || inode->i_size & 0x80000000UL))
246501c6 1614 ctx->large_files++;
3839e657 1615 if (pb.num_blocks != inode->i_blocks) {
21c84b71 1616 pctx->num = pb.num_blocks;
1b6bf175 1617 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
3839e657 1618 inode->i_blocks = pb.num_blocks;
503f9e7f 1619 dirty_inode++;
21c84b71
TT
1620 }
1621 pctx->num = 0;
3839e657 1622 }
503f9e7f
TT
1623out:
1624 if (dirty_inode)
1625 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
50e1e10f
TT
1626}
1627
21c84b71 1628#if 0
50e1e10f
TT
1629/*
1630 * Helper function called by process block when an illegal block is
1631 * found. It returns a description about why the block is illegal
1632 */
1633static char *describe_illegal_block(ext2_filsys fs, blk_t block)
1634{
1635 blk_t super;
1636 int i;
1637 static char problem[80];
1638
1639 super = fs->super->s_first_data_block;
1640 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
1641 if (block < super) {
1642 sprintf(problem, "< FIRSTBLOCK (%u)", super);
1643 return(problem);
1644 } else if (block >= fs->super->s_blocks_count) {
1645 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
1646 return(problem);
1647 }
1648 for (i = 0; i < fs->group_desc_count; i++) {
1649 if (block == super) {
1650 sprintf(problem, "is the superblock in group %d", i);
1651 break;
1652 }
1653 if (block > super &&
1654 block <= (super + fs->desc_blocks)) {
1655 sprintf(problem, "is in the group descriptors "
1656 "of group %d", i);
1657 break;
1658 }
1659 if (block == fs->group_desc[i].bg_block_bitmap) {
1660 sprintf(problem, "is the block bitmap of group %d", i);
1661 break;
1662 }
1663 if (block == fs->group_desc[i].bg_inode_bitmap) {
1664 sprintf(problem, "is the inode bitmap of group %d", i);
1665 break;
1666 }
1667 if (block >= fs->group_desc[i].bg_inode_table &&
1668 (block < fs->group_desc[i].bg_inode_table
1669 + fs->inode_blocks_per_group)) {
1670 sprintf(problem, "is in the inode table of group %d",
1671 i);
1672 break;
1673 }
1674 super += fs->super->s_blocks_per_group;
1675 }
1676 return(problem);
1677}
21c84b71 1678#endif
3839e657
TT
1679
1680/*
1681 * This is a helper function for check_blocks().
1682 */
53ef44c4 1683static int process_block(ext2_filsys fs,
3839e657 1684 blk_t *block_nr,
9d1bd3de 1685 e2_blkcnt_t blockcnt,
54434927
TT
1686 blk_t ref_block EXT2FS_ATTR((unused)),
1687 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 1688 void *priv_data)
3839e657
TT
1689{
1690 struct process_block_struct *p;
21c84b71 1691 struct problem_context *pctx;
3839e657 1692 blk_t blk = *block_nr;
50e1e10f 1693 int ret_code = 0;
21c84b71 1694 int problem = 0;
1b6bf175 1695 e2fsck_t ctx;
3839e657 1696
54dc7ca2 1697 p = (struct process_block_struct *) priv_data;
21c84b71 1698 pctx = p->pctx;
1b6bf175 1699 ctx = p->ctx;
3839e657 1700
1917875f
TT
1701 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
1702 /* todo: Check that the comprblk_fl is high, that the
1703 blkaddr pattern looks right (all non-holes up to
1704 first EXT2FS_COMPRESSED_BLKADDR, then all
1705 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
1706 that the feature_incompat bit is high, and that the
1707 inode is a regular file. If we're doing a "full
1708 check" (a concept introduced to e2fsck by e2compr,
1709 meaning that we look at data blocks as well as
1710 metadata) then call some library routine that
1711 checks the compressed data. I'll have to think
1712 about this, because one particularly important
1713 problem to be able to fix is to recalculate the
1714 cluster size if necessary. I think that perhaps
1715 we'd better do most/all e2compr-specific checks
1716 separately, after the non-e2compr checks. If not
1717 doing a full check, it may be useful to test that
1718 the personality is linux; e.g. if it isn't then
1719 perhaps this really is just an illegal block. */
1720 return 0;
1721 }
b94a052a 1722
50e1e10f
TT
1723 if (blk == 0) {
1724 if (p->is_dir == 0) {
1e3472c5
TT
1725 /*
1726 * Should never happen, since only directories
1727 * get called with BLOCK_FLAG_HOLE
1728 */
1b6bf175 1729#if DEBUG_E2FSCK
50e1e10f 1730 printf("process_block() called with blk == 0, "
5c576477
TT
1731 "blockcnt=%d, inode %lu???\n",
1732 blockcnt, p->ino);
1b6bf175 1733#endif
50e1e10f
TT
1734 return 0;
1735 }
1736 if (blockcnt < 0)
1737 return 0;
1738 if (blockcnt * fs->blocksize < p->inode->i_size) {
21c84b71
TT
1739#if 0
1740 printf("Missing block (#%d) in directory inode %lu!\n",
1741 blockcnt, p->ino);
1742#endif
50e1e10f
TT
1743 goto mark_dir;
1744 }
1745 return 0;
1746 }
1747
3839e657 1748#if 0
50e1e10f 1749 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
3839e657 1750 blockcnt);
50e1e10f 1751#endif
3839e657 1752
74becf3c
TT
1753 /*
1754 * Simplistic fragmentation check. We merely require that the
1755 * file be contiguous. (Which can never be true for really
1756 * big files that are greater than a block group.)
1757 */
1917875f 1758 if (!HOLE_BLKADDR(p->previous_block)) {
74becf3c
TT
1759 if (p->previous_block+1 != blk)
1760 p->fragmented = 1;
1761 }
1762 p->previous_block = blk;
503f9e7f 1763
8421fb67 1764 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
da307041
TT
1765 problem = PR_1_TOOBIG_DIR;
1766 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
1767 problem = PR_1_TOOBIG_REG;
1768 if (!p->is_dir && !p->is_reg && blockcnt > 0)
1769 problem = PR_1_TOOBIG_SYMLINK;
1770
50e1e10f 1771 if (blk < fs->super->s_first_data_block ||
21c84b71
TT
1772 blk >= fs->super->s_blocks_count)
1773 problem = PR_1_ILLEGAL_BLOCK_NUM;
21c84b71
TT
1774
1775 if (problem) {
f3db3566 1776 p->num_illegal_blocks++;
21c84b71 1777 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
1b6bf175 1778 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
f3db3566
TT
1779 p->clear = 1;
1780 return BLOCK_ABORT;
1781 }
f8188fff 1782 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
f3db3566 1783 p->suppress = 1;
1b6bf175
TT
1784 set_latch_flags(PR_LATCH_BLOCK,
1785 PRL_SUPPRESS, 0);
f3db3566
TT
1786 }
1787 }
21c84b71
TT
1788 pctx->blk = blk;
1789 pctx->blkcount = blockcnt;
1b6bf175 1790 if (fix_problem(ctx, problem, pctx)) {
50e1e10f
TT
1791 blk = *block_nr = 0;
1792 ret_code = BLOCK_CHANGED;
1793 goto mark_dir;
21c84b71 1794 } else
3839e657 1795 return 0;
3839e657
TT
1796 }
1797
d323f8fb 1798 if (p->ino == EXT2_RESIZE_INO) {
c3ffaf83
TT
1799 /*
1800 * The resize inode has already be sanity checked
1801 * during pass #0 (the superblock checks). All we
1802 * have to do is mark the double indirect block as
1803 * being in use; all of the other blocks are handled
1804 * by mark_table_blocks()).
1805 */
1806 if (blockcnt == BLOCK_COUNT_DIND)
d323f8fb
TT
1807 mark_block_used(ctx, blk);
1808 } else
1809 mark_block_used(ctx, blk);
50e1e10f 1810 p->num_blocks++;
1e3472c5
TT
1811 if (blockcnt >= 0)
1812 p->last_block = blockcnt;
50e1e10f 1813mark_dir:
1e3472c5 1814 if (p->is_dir && (blockcnt >= 0)) {
1b6bf175
TT
1815 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
1816 blk, blockcnt);
1817 if (pctx->errcode) {
1818 pctx->blk = blk;
1819 pctx->num = blockcnt;
1820 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
08b21301
TT
1821 /* Should never get here */
1822 ctx->flags |= E2F_FLAG_ABORT;
1823 return BLOCK_ABORT;
3839e657 1824 }
3839e657 1825 }
50e1e10f 1826 return ret_code;
3839e657
TT
1827}
1828
53ef44c4 1829static int process_bad_block(ext2_filsys fs,
3839e657 1830 blk_t *block_nr,
9d1bd3de 1831 e2_blkcnt_t blockcnt,
54434927
TT
1832 blk_t ref_block EXT2FS_ATTR((unused)),
1833 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 1834 void *priv_data)
3839e657
TT
1835{
1836 struct process_block_struct *p;
3839e657 1837 blk_t blk = *block_nr;
54434927
TT
1838 blk_t first_block;
1839 dgrp_t i;
21c84b71 1840 struct problem_context *pctx;
1b6bf175 1841 e2fsck_t ctx;
21c84b71 1842
1917875f
TT
1843 /*
1844 * Note: This function processes blocks for the bad blocks
1845 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
1846 */
1847
3839e657
TT
1848 if (!blk)
1849 return 0;
21c84b71 1850
54dc7ca2 1851 p = (struct process_block_struct *) priv_data;
1b6bf175 1852 ctx = p->ctx;
21c84b71
TT
1853 pctx = p->pctx;
1854
f8188fff 1855 pctx->ino = EXT2_BAD_INO;
21c84b71
TT
1856 pctx->blk = blk;
1857 pctx->blkcount = blockcnt;
3839e657
TT
1858
1859 if ((blk < fs->super->s_first_data_block) ||
1860 (blk >= fs->super->s_blocks_count)) {
1b6bf175 1861 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
3839e657
TT
1862 *block_nr = 0;
1863 return BLOCK_CHANGED;
21c84b71 1864 } else
3839e657 1865 return 0;
3839e657
TT
1866 }
1867
1868 if (blockcnt < 0) {
000ba404
TT
1869 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
1870 p->bbcheck = 1;
1871 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
1872 *block_nr = 0;
1873 return BLOCK_CHANGED;
1874 }
1875 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
1876 blk)) {
1877 p->bbcheck = 1;
1878 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
1879 pctx)) {
1880 *block_nr = 0;
1881 return BLOCK_CHANGED;
1882 }
a02ce9df 1883 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
1884 return BLOCK_ABORT;
1885 } else
1b6bf175 1886 mark_block_used(ctx, blk);
3839e657
TT
1887 return 0;
1888 }
1889#if 0
50e1e10f 1890 printf ("DEBUG: Marking %u as bad.\n", blk);
3839e657 1891#endif
1b6bf175 1892 ctx->fs_badblocks_count++;
3839e657
TT
1893 /*
1894 * If the block is not used, then mark it as used and return.
1895 * If it is already marked as found, this must mean that
1896 * there's an overlap between the filesystem table blocks
1897 * (bitmaps and inode table) and the bad block list.
1898 */
1b6bf175
TT
1899 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1900 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
3839e657
TT
1901 return 0;
1902 }
f3db3566
TT
1903 /*
1904 * Try to find the where the filesystem block was used...
1905 */
1906 first_block = fs->super->s_first_data_block;
1907
1908 for (i = 0; i < fs->group_desc_count; i++ ) {
21c84b71 1909 pctx->group = i;
1b6bf175 1910 pctx->blk = blk;
8039c480
TT
1911 if (!ext2fs_bg_has_super(fs, i))
1912 goto skip_super;
f3db3566
TT
1913 if (blk == first_block) {
1914 if (i == 0) {
1b6bf175
TT
1915 if (fix_problem(ctx,
1916 PR_1_BAD_PRIMARY_SUPERBLOCK,
1917 pctx)) {
1918 *block_nr = 0;
50e1e10f 1919 return BLOCK_CHANGED;
1b6bf175 1920 }
50e1e10f 1921 return 0;
f3db3566 1922 }
1b6bf175 1923 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
f3db3566
TT
1924 return 0;
1925 }
1926 if ((blk > first_block) &&
1927 (blk <= first_block + fs->desc_blocks)) {
1928 if (i == 0) {
1b6bf175
TT
1929 pctx->blk = *block_nr;
1930 if (fix_problem(ctx,
1931 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
1932 *block_nr = 0;
50e1e10f 1933 return BLOCK_CHANGED;
1b6bf175 1934 }
50e1e10f 1935 return 0;
f3db3566 1936 }
1b6bf175 1937 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
f3db3566 1938 return 0;
3839e657 1939 }
8039c480 1940 skip_super:
f3db3566 1941 if (blk == fs->group_desc[i].bg_block_bitmap) {
1b6bf175
TT
1942 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
1943 ctx->invalid_block_bitmap_flag[i]++;
1944 ctx->invalid_bitmaps++;
21c84b71 1945 }
f3db3566
TT
1946 return 0;
1947 }
1948 if (blk == fs->group_desc[i].bg_inode_bitmap) {
1b6bf175
TT
1949 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
1950 ctx->invalid_inode_bitmap_flag[i]++;
1951 ctx->invalid_bitmaps++;
21c84b71 1952 }
f3db3566
TT
1953 return 0;
1954 }
1955 if ((blk >= fs->group_desc[i].bg_inode_table) &&
1956 (blk < (fs->group_desc[i].bg_inode_table +
1957 fs->inode_blocks_per_group))) {
21c84b71
TT
1958 /*
1959 * If there are bad blocks in the inode table,
1960 * the inode scan code will try to do
1961 * something reasonable automatically.
1962 */
f3db3566
TT
1963 return 0;
1964 }
8039c480 1965 first_block += fs->super->s_blocks_per_group;
f3db3566
TT
1966 }
1967 /*
1968 * If we've gotten to this point, then the only
1969 * possibility is that the bad block inode meta data
1970 * is using a bad block.
1971 */
1972 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
000ba404
TT
1973 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
1974 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
1975 p->bbcheck = 1;
1976 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
1977 *block_nr = 0;
1978 return BLOCK_CHANGED;
1979 }
a02ce9df 1980 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301 1981 return BLOCK_ABORT;
f3db3566 1982 return 0;
3839e657 1983 }
1b6bf175
TT
1984
1985 pctx->group = -1;
1986
1987 /* Warn user that the block wasn't claimed */
1988 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
1989
f3db3566 1990 return 0;
3839e657
TT
1991}
1992
1b6bf175 1993static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
3839e657
TT
1994 const char *name, int num, blk_t *new_block)
1995{
1b6bf175 1996 ext2_filsys fs = ctx->fs;
3839e657 1997 blk_t old_block = *new_block;
abf23439 1998 blk_t last_block;
3839e657
TT
1999 int i;
2000 char *buf;
1b6bf175
TT
2001 struct problem_context pctx;
2002
2003 clear_problem_context(&pctx);
2004
2005 pctx.group = group;
2006 pctx.blk = old_block;
2007 pctx.str = name;
2008
abf23439
ES
2009 last_block = ext2fs_group_last_block(fs, group);
2010 pctx.errcode = ext2fs_get_free_blocks(fs, first_block, last_block,
1b6bf175
TT
2011 num, ctx->block_found_map, new_block);
2012 if (pctx.errcode) {
2013 pctx.num = num;
2014 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
3839e657
TT
2015 ext2fs_unmark_valid(fs);
2016 return;
2017 }
c4e3d3f3 2018 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
08b21301 2019 if (pctx.errcode) {
1b6bf175 2020 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
3839e657
TT
2021 ext2fs_unmark_valid(fs);
2022 return;
2023 }
2024 ext2fs_mark_super_dirty(fs);
299d7424 2025 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
1b6bf175
TT
2026 pctx.blk2 = *new_block;
2027 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
2028 PR_1_RELOC_TO), &pctx);
2029 pctx.blk2 = 0;
3839e657 2030 for (i = 0; i < num; i++) {
1b6bf175
TT
2031 pctx.blk = i;
2032 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
f3db3566 2033 if (old_block) {
1b6bf175
TT
2034 pctx.errcode = io_channel_read_blk(fs->io,
2035 old_block + i, 1, buf);
2036 if (pctx.errcode)
2037 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
f3db3566
TT
2038 } else
2039 memset(buf, 0, fs->blocksize);
2040
1b6bf175
TT
2041 pctx.blk = (*new_block) + i;
2042 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
3839e657 2043 1, buf);
1b6bf175
TT
2044 if (pctx.errcode)
2045 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
3839e657 2046 }
c4e3d3f3 2047 ext2fs_free_mem(&buf);
3839e657
TT
2048}
2049
2050/*
f3db3566
TT
2051 * This routine gets called at the end of pass 1 if bad blocks are
2052 * detected in the superblock, group descriptors, inode_bitmaps, or
2053 * block bitmaps. At this point, all of the blocks have been mapped
2054 * out, so we can try to allocate new block(s) to replace the bad
2055 * blocks.
3839e657 2056 */
1b6bf175 2057static void handle_fs_bad_blocks(e2fsck_t ctx)
3839e657 2058{
1b6bf175 2059 ext2_filsys fs = ctx->fs;
54434927 2060 dgrp_t i;
d1b4b85c 2061 blk_t first_block;
3839e657
TT
2062
2063 for (i = 0; i < fs->group_desc_count; i++) {
abf23439
ES
2064 first_block = ext2fs_group_first_block(fs, i);
2065
1b6bf175 2066 if (ctx->invalid_block_bitmap_flag[i]) {
0c4a0726 2067 new_table_block(ctx, first_block, i, _("block bitmap"),
1b6bf175 2068 1, &fs->group_desc[i].bg_block_bitmap);
3839e657 2069 }
1b6bf175 2070 if (ctx->invalid_inode_bitmap_flag[i]) {
0c4a0726 2071 new_table_block(ctx, first_block, i, _("inode bitmap"),
1b6bf175 2072 1, &fs->group_desc[i].bg_inode_bitmap);
3839e657 2073 }
1b6bf175 2074 if (ctx->invalid_inode_table_flag[i]) {
0c4a0726 2075 new_table_block(ctx, first_block, i, _("inode table"),
f3db3566 2076 fs->inode_blocks_per_group,
3839e657 2077 &fs->group_desc[i].bg_inode_table);
08b21301 2078 ctx->flags |= E2F_FLAG_RESTART;
3839e657 2079 }
3839e657 2080 }
1b6bf175 2081 ctx->invalid_bitmaps = 0;
3839e657
TT
2082}
2083
2084/*
2085 * This routine marks all blocks which are used by the superblock,
2086 * group descriptors, inode bitmaps, and block bitmaps.
2087 */
1b6bf175 2088static void mark_table_blocks(e2fsck_t ctx)
3839e657 2089{
1b6bf175 2090 ext2_filsys fs = ctx->fs;
62c6d140 2091 blk_t b;
54434927
TT
2092 dgrp_t i;
2093 int j;
21c84b71
TT
2094 struct problem_context pctx;
2095
2096 clear_problem_context(&pctx);
3839e657 2097
3839e657 2098 for (i = 0; i < fs->group_desc_count; i++) {
21c84b71 2099 pctx.group = i;
da2e97f7 2100
ef344e13
TT
2101 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
2102
21c84b71
TT
2103 /*
2104 * Mark the blocks used for the inode table
2105 */
2106 if (fs->group_desc[i].bg_inode_table) {
2107 for (j = 0, b = fs->group_desc[i].bg_inode_table;
2108 j < fs->inode_blocks_per_group;
2109 j++, b++) {
1b6bf175 2110 if (ext2fs_test_block_bitmap(ctx->block_found_map,
21c84b71
TT
2111 b)) {
2112 pctx.blk = b;
1b6bf175 2113 if (fix_problem(ctx,
21c84b71 2114 PR_1_ITABLE_CONFLICT, &pctx)) {
1b6bf175
TT
2115 ctx->invalid_inode_table_flag[i]++;
2116 ctx->invalid_bitmaps++;
21c84b71
TT
2117 }
2118 } else {
1b6bf175 2119 ext2fs_mark_block_bitmap(ctx->block_found_map,
21c84b71 2120 b);
21c84b71
TT
2121 }
2122 }
2123 }
2124
3839e657
TT
2125 /*
2126 * Mark block used for the block bitmap
2127 */
f3db3566 2128 if (fs->group_desc[i].bg_block_bitmap) {
1b6bf175 2129 if (ext2fs_test_block_bitmap(ctx->block_found_map,
f3db3566 2130 fs->group_desc[i].bg_block_bitmap)) {
21c84b71 2131 pctx.blk = fs->group_desc[i].bg_block_bitmap;
1b6bf175
TT
2132 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
2133 ctx->invalid_block_bitmap_flag[i]++;
2134 ctx->invalid_bitmaps++;
f3db3566 2135 }
50e1e10f 2136 } else {
1b6bf175 2137 ext2fs_mark_block_bitmap(ctx->block_found_map,
f3db3566 2138 fs->group_desc[i].bg_block_bitmap);
50e1e10f
TT
2139 }
2140
f3db3566 2141 }
3839e657
TT
2142 /*
2143 * Mark block used for the inode bitmap
2144 */
f3db3566 2145 if (fs->group_desc[i].bg_inode_bitmap) {
1b6bf175 2146 if (ext2fs_test_block_bitmap(ctx->block_found_map,
f3db3566 2147 fs->group_desc[i].bg_inode_bitmap)) {
21c84b71 2148 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
1b6bf175
TT
2149 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
2150 ctx->invalid_inode_bitmap_flag[i]++;
2151 ctx->invalid_bitmaps++;
21c84b71 2152 }
50e1e10f 2153 } else {
1b6bf175 2154 ext2fs_mark_block_bitmap(ctx->block_found_map,
f3db3566 2155 fs->group_desc[i].bg_inode_bitmap);
50e1e10f 2156 }
f3db3566 2157 }
3839e657
TT
2158 }
2159}
2160
2161/*
e72a9ba3 2162 * Thes subroutines short circuits ext2fs_get_blocks and
3839e657
TT
2163 * ext2fs_check_directory; we use them since we already have the inode
2164 * structure, so there's no point in letting the ext2fs library read
2165 * the inode again.
2166 */
86c627ec
TT
2167static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
2168 blk_t *blocks)
3839e657 2169{
54dc7ca2 2170 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3839e657
TT
2171 int i;
2172
71d521c6 2173 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
521e3685
TT
2174 return EXT2_ET_CALLBACK_NOTHANDLED;
2175
2176 for (i=0; i < EXT2_N_BLOCKS; i++)
1b6bf175 2177 blocks[i] = ctx->stashed_inode->i_block[i];
521e3685 2178 return 0;
3839e657
TT
2179}
2180
86c627ec 2181static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
e72a9ba3 2182 struct ext2_inode *inode)
1e3472c5 2183{
54dc7ca2 2184 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2185
71d521c6 2186 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1e3472c5 2187 return EXT2_ET_CALLBACK_NOTHANDLED;
1b6bf175 2188 *inode = *ctx->stashed_inode;
1e3472c5
TT
2189 return 0;
2190}
2191
86c627ec 2192static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
1e3472c5
TT
2193 struct ext2_inode *inode)
2194{
54dc7ca2 2195 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2196
27431595
TT
2197 if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
2198 (inode != ctx->stashed_inode))
1b6bf175 2199 *ctx->stashed_inode = *inode;
1e3472c5
TT
2200 return EXT2_ET_CALLBACK_NOTHANDLED;
2201}
2202
86c627ec 2203static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
3839e657 2204{
54dc7ca2 2205 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2206
71d521c6 2207 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1b6bf175
TT
2208 return EXT2_ET_CALLBACK_NOTHANDLED;
2209
2210 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
291c9049 2211 return EXT2_ET_NO_DIRECTORY;
1b6bf175 2212 return 0;
3839e657 2213}
e72a9ba3
TT
2214
2215void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
2216{
2217 ext2_filsys fs = ctx->fs;
2218
2219 if (bool) {
2220 fs->get_blocks = pass1_get_blocks;
2221 fs->check_directory = pass1_check_directory;
2222 fs->read_inode = pass1_read_inode;
2223 fs->write_inode = pass1_write_inode;
2224 ctx->stashed_ino = 0;
2225 } else {
2226 fs->get_blocks = 0;
2227 fs->check_directory = 0;
2228 fs->read_inode = 0;
2229 fs->write_inode = 0;
2230 }
2231}