]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - e2fsck/pass1.c
e2fsck: check ea-in-inode regions for overlap
[thirdparty/e2fsprogs.git] / e2fsck / pass1.c
CommitLineData
3839e657
TT
1/*
2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
efc6f628 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%
efc6f628 10 *
3839e657
TT
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() */
d1154eb4 41#include "config.h"
3e699064 42#include <string.h>
3839e657 43#include <time.h>
50e1e10f
TT
44#ifdef HAVE_ERRNO_H
45#include <errno.h>
46#endif
3839e657 47
3839e657 48#include "e2fsck.h"
342d847d
TT
49#include <ext2fs/ext2_ext_attr.h>
50
21c84b71 51#include "problem.h"
3839e657 52
50e1e10f
TT
53#ifdef NO_INLINE_FUNCS
54#define _INLINE_
55#else
56#define _INLINE_ inline
57#endif
58
6dc64392
VAH
59static int process_block(ext2_filsys fs, blk64_t *blocknr,
60 e2_blkcnt_t blockcnt, blk64_t ref_blk,
54dc7ca2 61 int ref_offset, void *priv_data);
6dc64392
VAH
62static int process_bad_block(ext2_filsys fs, blk64_t *block_nr,
63 e2_blkcnt_t blockcnt, blk64_t ref_blk,
54dc7ca2 64 int ref_offset, void *priv_data);
1b6bf175 65static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657 66 char *block_buf);
1b6bf175 67static void mark_table_blocks(e2fsck_t ctx);
1b6bf175 68static void alloc_bb_map(e2fsck_t ctx);
aa4115a4 69static void alloc_imagic_map(e2fsck_t ctx);
fdbdea09 70static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
1b6bf175
TT
71static void handle_fs_bad_blocks(e2fsck_t ctx);
72static void process_inodes(e2fsck_t ctx, char *block_buf);
4c77fe50 73static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
f3db3566 74static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
54dc7ca2 75 dgrp_t group, void * priv_data);
efc6f628 76static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
e8a3ee62 77 char *block_buf, int adjust_sign);
6dc64392 78/* static char *describe_illegal_block(ext2_filsys fs, blk64_t block); */
3839e657
TT
79
80struct process_block_struct {
86c627ec 81 ext2_ino_t ino;
83e692e8 82 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
23d6dd1f
DW
83 fragmented:1, compressed:1, bbcheck:1,
84 inode_modified:1;
65d71894 85 blk64_t num_blocks;
6dc64392 86 blk64_t max_blocks;
9d1bd3de 87 e2_blkcnt_t last_block;
010dc7b9 88 e2_blkcnt_t last_init_lblock;
4dbe79bc 89 e2_blkcnt_t last_db_block;
246501c6 90 int num_illegal_blocks;
6dc64392 91 blk64_t previous_block;
f3db3566 92 struct ext2_inode *inode;
21c84b71 93 struct problem_context *pctx;
000ba404 94 ext2fs_block_bitmap fs_meta_blocks;
1b6bf175 95 e2fsck_t ctx;
35c8faaf 96 blk64_t bad_ref;
3839e657
TT
97};
98
99struct process_inode_block {
86c627ec 100 ext2_ino_t ino;
3839e657
TT
101 struct ext2_inode inode;
102};
103
f8188fff
TT
104struct scan_callback_struct {
105 e2fsck_t ctx;
106 char *block_buf;
107};
108
3839e657
TT
109/*
110 * For the inodes to process list.
111 */
112static struct process_inode_block *inodes_to_process;
113static int process_inode_count;
3839e657 114
7823dd65
TT
115static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
116 EXT2_MIN_BLOCK_LOG_SIZE + 1];
246501c6 117
f3db3566
TT
118/*
119 * Free all memory allocated by pass1 in preparation for restarting
120 * things.
121 */
54434927 122static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
f3db3566 123{
c4e3d3f3 124 ext2fs_free_mem(&inodes_to_process);
08b21301 125 inodes_to_process = 0;
f3db3566
TT
126}
127
7cf73dcd
TT
128/*
129 * Check to make sure a device inode is real. Returns 1 if the device
130 * checks out, 0 if not.
1dde43f0
TT
131 *
132 * Note: this routine is now also used to check FIFO's and Sockets,
133 * since they have the same requirement; the i_block fields should be
efc6f628 134 * zero.
7cf73dcd 135 */
efc6f628 136int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
f954ba01 137 struct ext2_inode *inode)
7cf73dcd
TT
138{
139 int i;
140
a40ecbb1 141 /*
441ab1e0
TT
142 * If the index flag is set, then this is a bogus
143 * device/fifo/socket
a40ecbb1 144 */
441ab1e0 145 if (inode->i_flags & EXT2_INDEX_FL)
53abed0a 146 return 0;
bcf9c5d4 147
7fdfabd3
TT
148 /*
149 * We should be able to do the test below all the time, but
150 * because the kernel doesn't forcibly clear the device
151 * inode's additional i_block fields, there are some rare
152 * occasions when a legitimate device inode will have non-zero
153 * additional i_block fields. So for now, we only complain
154 * when the immutable flag is set, which should never happen
155 * for devices. (And that's when the problem is caused, since
156 * you can't set or clear immutable flags for devices.) Once
157 * the kernel has been fixed we can change this...
158 */
01fbc701 159 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
efc6f628 160 for (i=4; i < EXT2_N_BLOCKS; i++)
7fdfabd3
TT
161 if (inode->i_block[i])
162 return 0;
163 }
7cf73dcd
TT
164 return 1;
165}
166
67052a8a
AD
167/*
168 * Check to make sure a symlink inode is real. Returns 1 if the symlink
169 * checks out, 0 if not.
170 */
7cadc577
TT
171int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
172 struct ext2_inode *inode, char *buf)
67052a8a 173{
54434927 174 unsigned int len;
d007cb4c 175 int i;
6dc64392 176 blk64_t blocks;
7cadc577
TT
177 ext2_extent_handle_t handle;
178 struct ext2_extent_info info;
179 struct ext2fs_extent extent;
67052a8a 180
bcf9c5d4 181 if ((inode->i_size_high || inode->i_size == 0) ||
f9f8fded 182 (inode->i_flags & EXT2_INDEX_FL))
67052a8a
AD
183 return 0;
184
7cadc577
TT
185 if (inode->i_flags & EXT4_EXTENTS_FL) {
186 if (inode->i_size > fs->blocksize)
187 return 0;
84b239ae 188 if (ext2fs_extent_open2(fs, ino, inode, &handle))
7cadc577
TT
189 return 0;
190 i = 0;
191 if (ext2fs_extent_get_info(handle, &info) ||
192 (info.num_entries != 1) ||
193 (info.max_depth != 0))
194 goto exit_extent;
195 if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent) ||
196 (extent.e_lblk != 0) ||
197 (extent.e_len != 1) ||
198 (extent.e_pblk < fs->super->s_first_data_block) ||
4efbac6f 199 (extent.e_pblk >= ext2fs_blocks_count(fs->super)))
7cadc577
TT
200 goto exit_extent;
201 i = 1;
202 exit_extent:
203 ext2fs_extent_free(handle);
204 return i;
205 }
206
f9f8fded
ZL
207 if (inode->i_flags & EXT4_INLINE_DATA_FL) {
208 size_t inline_size;
209
210 if (ext2fs_inline_data_size(fs, ino, &inline_size))
211 return 0;
212 if (inode->i_size != inline_size)
213 return 0;
214
215 return 1;
216 }
217
6dc64392 218 blocks = ext2fs_inode_data_blocks2(fs, inode);
0684a4f3 219 if (blocks) {
b94a052a 220 if ((inode->i_size >= fs->blocksize) ||
0684a4f3 221 (blocks != fs->blocksize >> 9) ||
d007cb4c 222 (inode->i_block[0] < fs->super->s_first_data_block) ||
4efbac6f 223 (inode->i_block[0] >= ext2fs_blocks_count(fs->super)))
67052a8a
AD
224 return 0;
225
226 for (i = 1; i < EXT2_N_BLOCKS; i++)
227 if (inode->i_block[i])
228 return 0;
b94a052a 229
24a117ab 230 if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf))
b94a052a
AD
231 return 0;
232
233 len = strnlen(buf, fs->blocksize);
234 if (len == fs->blocksize)
235 return 0;
67052a8a 236 } else {
b94a052a 237 if (inode->i_size >= sizeof(inode->i_block))
67052a8a
AD
238 return 0;
239
b94a052a
AD
240 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
241 if (len == sizeof(inode->i_block))
67052a8a
AD
242 return 0;
243 }
b94a052a
AD
244 if (len != inode->i_size)
245 return 0;
67052a8a
AD
246 return 1;
247}
248
6fdc7a32 249/*
01fbc701
TT
250 * If the immutable (or append-only) flag is set on the inode, offer
251 * to clear it.
6fdc7a32 252 */
bcf9c5d4 253#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
6fdc7a32
TT
254static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
255{
b94a052a 256 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
6fdc7a32
TT
257 return;
258
259 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
260 return;
261
b94a052a 262 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
6fdc7a32
TT
263 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
264}
265
d647a1ea
TT
266/*
267 * If device, fifo or socket, check size is zero -- if not offer to
268 * clear it
269 */
270static void check_size(e2fsck_t ctx, struct problem_context *pctx)
271{
272 struct ext2_inode *inode = pctx->inode;
efc6f628 273
0bd0e593 274 if (EXT2_I_SIZE(inode) == 0)
d647a1ea 275 return;
efc6f628 276
85645a6f 277 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
d647a1ea 278 return;
efc6f628 279
97c607b1 280 ext2fs_inode_size_set(ctx->fs, inode, 0);
d647a1ea
TT
281 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
282}
efc6f628 283
cebe48a1
TT
284static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
285{
286 struct ext2_super_block *sb = ctx->fs->super;
287 struct ext2_inode_large *inode;
288 struct ext2_ext_attr_entry *entry;
78c666b8 289 char *start, *header;
1a8c2c4a 290 unsigned int storage_size, remain;
3c7c6d73 291 problem_t problem = 0;
78c666b8 292 region_t region = 0;
cebe48a1
TT
293
294 inode = (struct ext2_inode_large *) pctx->inode;
295 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
296 inode->i_extra_isize;
78c666b8
DW
297 header = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
298 inode->i_extra_isize;
299 start = header + sizeof(__u32);
cebe48a1
TT
300 entry = (struct ext2_ext_attr_entry *) start;
301
302 /* scan all entry's headers first */
303
304 /* take finish entry 0UL into account */
efc6f628 305 remain = storage_size - sizeof(__u32);
cebe48a1 306
78c666b8
DW
307 region = region_create(0, storage_size);
308 if (!region) {
309 fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
310 problem = 0;
311 ctx->flags |= E2F_FLAG_ABORT;
312 return;
313 }
314 if (region_allocate(region, 0, sizeof(__u32))) {
315 problem = PR_1_INODE_EA_ALLOC_COLLISION;
316 goto fix;
317 }
318
88334ce0
DW
319 while (remain >= sizeof(struct ext2_ext_attr_entry) &&
320 !EXT2_EXT_IS_LAST_ENTRY(entry)) {
fefaef39 321 __u32 hash;
cebe48a1 322
78c666b8
DW
323 if (region_allocate(region, (char *)entry - (char *)header,
324 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
325 problem = PR_1_INODE_EA_ALLOC_COLLISION;
326 goto fix;
327 }
328
cebe48a1
TT
329 /* header eats this space */
330 remain -= sizeof(struct ext2_ext_attr_entry);
efc6f628 331
cebe48a1
TT
332 /* is attribute name valid? */
333 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
334 pctx->num = entry->e_name_len;
335 problem = PR_1_ATTR_NAME_LEN;
336 goto fix;
337 }
338
339 /* attribute len eats this space */
340 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
341
342 /* check value size */
10fc3a63 343 if (entry->e_value_size > remain) {
cebe48a1
TT
344 pctx->num = entry->e_value_size;
345 problem = PR_1_ATTR_VALUE_SIZE;
346 goto fix;
347 }
348
cebe48a1
TT
349 /* e_value_block must be 0 in inode's ea */
350 if (entry->e_value_block != 0) {
351 pctx->num = entry->e_value_block;
352 problem = PR_1_ATTR_VALUE_BLOCK;
353 goto fix;
354 }
fefaef39 355
78c666b8
DW
356 if (entry->e_value_size &&
357 region_allocate(region, sizeof(__u32) + entry->e_value_offs,
358 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
359 problem = PR_1_INODE_EA_ALLOC_COLLISION;
360 goto fix;
361 }
362
fefaef39
AD
363 hash = ext2fs_ext_attr_hash_entry(entry,
364 start + entry->e_value_offs);
365
366 /* e_hash may be 0 in older inode's ea */
367 if (entry->e_hash != 0 && entry->e_hash != hash) {
cebe48a1
TT
368 pctx->num = entry->e_hash;
369 problem = PR_1_ATTR_HASH;
370 goto fix;
371 }
372
373 remain -= entry->e_value_size;
cebe48a1
TT
374
375 entry = EXT2_EXT_ATTR_NEXT(entry);
376 }
78c666b8
DW
377
378 if (region_allocate(region, (char *)entry - (char *)header,
379 sizeof(__u32))) {
380 problem = PR_1_INODE_EA_ALLOC_COLLISION;
381 goto fix;
382 }
cebe48a1 383fix:
78c666b8
DW
384 if (region)
385 region_free(region);
cebe48a1
TT
386 /*
387 * it seems like a corruption. it's very unlikely we could repair
388 * EA(s) in automatic fashion -bzzz
389 */
cebe48a1
TT
390 if (problem == 0 || !fix_problem(ctx, problem, pctx))
391 return;
392
fefaef39 393 /* simply remove all possible EA(s) */
78c666b8 394 *((__u32 *)header) = 0UL;
da938f20 395 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
cebe48a1
TT
396 EXT2_INODE_SIZE(sb), "pass1");
397}
398
399static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
400{
401 struct ext2_super_block *sb = ctx->fs->super;
402 struct ext2_inode_large *inode;
403 __u32 *eamagic;
404 int min, max;
405
406 inode = (struct ext2_inode_large *) pctx->inode;
407 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
408 /* this isn't large inode. so, nothing to check */
409 return;
410 }
411
412#if 0
413 printf("inode #%u, i_extra_size %d\n", pctx->ino,
414 inode->i_extra_isize);
efc6f628 415#endif
89efc88e
TT
416 /* i_extra_isize must cover i_extra_isize + i_checksum_hi at least */
417 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_checksum_hi);
cebe48a1 418 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
efc6f628 419 /*
cebe48a1
TT
420 * For now we will allow i_extra_isize to be 0, but really
421 * implementations should never allow i_extra_isize to be 0
422 */
423 if (inode->i_extra_isize &&
424 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
425 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
426 return;
427 inode->i_extra_isize = min;
428 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
429 EXT2_INODE_SIZE(sb), "pass1");
430 return;
431 }
432
433 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
434 inode->i_extra_isize);
435 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
436 /* it seems inode has an extended attribute(s) in body */
437 check_ea_in_inode(ctx, pctx);
438 }
439}
6fdc7a32 440
efc6f628 441/*
fbc3f901
TT
442 * Check to see if the inode might really be a directory, despite i_mode
443 *
444 * This is a lot of complexity for something for which I'm not really
445 * convinced happens frequently in the wild. If for any reason this
446 * causes any problems, take this code out.
447 * [tytso:20070331.0827EDT]
448 */
449static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
450 char *buf)
451{
452 struct ext2_inode *inode = pctx->inode;
fbc3f901 453 struct ext2_dir_entry *dirent;
e94bc631 454 errcode_t retval;
cf5301d7 455 blk64_t blk;
03fa6f8a 456 unsigned int i, rec_len, not_device = 0;
1ec42a00 457 int extent_fs;
042e0719 458 int inlinedata_fs;
fbc3f901 459
1ec42a00
ND
460 /*
461 * If the mode looks OK, we believe it. If the first block in
462 * the i_block array is 0, this cannot be a directory. If the
463 * inode is extent-mapped, it is still the case that the latter
464 * cannot be 0 - the magic number in the extent header would make
465 * it nonzero.
466 */
fbc3f901 467 if (LINUX_S_ISDIR(inode->i_mode) || LINUX_S_ISREG(inode->i_mode) ||
0eeb1549 468 LINUX_S_ISLNK(inode->i_mode) || inode->i_block[0] == 0)
fbc3f901
TT
469 return;
470
1ec42a00
ND
471 /*
472 * Check the block numbers in the i_block array for validity:
473 * zero blocks are skipped (but the first one cannot be zero -
474 * see above), other blocks are checked against the first and
475 * max data blocks (from the the superblock) and against the
476 * block bitmap. Any invalid block found means this cannot be
477 * a directory.
478 *
479 * If there are non-zero blocks past the fourth entry, then
480 * this cannot be a device file: we remember that for the next
481 * check.
482 *
483 * For extent mapped files, we don't do any sanity checking:
484 * just try to get the phys block of logical block 0 and run
485 * with it.
042e0719
ZL
486 *
487 * For inline data files, we just try to get the size of inline
488 * data. If it's true, we will treat it as a directory.
1ec42a00
ND
489 */
490
cf5301d7
AD
491 extent_fs = (ctx->fs->super->s_feature_incompat &
492 EXT3_FEATURE_INCOMPAT_EXTENTS);
042e0719
ZL
493 inlinedata_fs = (ctx->fs->super->s_feature_incompat &
494 EXT4_FEATURE_INCOMPAT_INLINE_DATA);
495 if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL)) {
24997f1c 496 size_t size;
042e0719
ZL
497
498 if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
499 return;
500 /* device files never have a "system.data" entry */
501 goto isdir;
502 } else if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {
1ec42a00 503 /* extent mapped */
6dc64392 504 if (ext2fs_bmap2(ctx->fs, pctx->ino, inode, 0, 0, 0, 0,
1ec42a00
ND
505 &blk))
506 return;
507 /* device files are never extent mapped */
508 not_device++;
509 } else {
510 for (i=0; i < EXT2_N_BLOCKS; i++) {
511 blk = inode->i_block[i];
512 if (!blk)
513 continue;
514 if (i >= 4)
515 not_device++;
516
517 if (blk < ctx->fs->super->s_first_data_block ||
cc84d866
TT
518 blk >= ext2fs_blocks_count(ctx->fs->super) ||
519 ext2fs_fast_test_block_bitmap2(ctx->block_found_map,
520 blk))
1ec42a00
ND
521 return; /* Invalid block, can't be dir */
522 }
523 blk = inode->i_block[0];
fbc3f901
TT
524 }
525
1ec42a00
ND
526 /*
527 * If the mode says this is a device file and the i_links_count field
528 * is sane and we have not ruled it out as a device file previously,
529 * we declare it a device file, not a directory.
530 */
efc6f628 531 if ((LINUX_S_ISCHR(inode->i_mode) || LINUX_S_ISBLK(inode->i_mode)) &&
fbc3f901
TT
532 (inode->i_links_count == 1) && !not_device)
533 return;
534
1ec42a00 535 /* read the first block */
f85a9ae6 536 ehandler_operation(_("reading directory block"));
81683c6a 537 retval = ext2fs_read_dir_block4(ctx->fs, blk, buf, 0, pctx->ino);
e94bc631
TT
538 ehandler_operation(0);
539 if (retval)
fbc3f901
TT
540 return;
541
542 dirent = (struct ext2_dir_entry *) buf;
8a480350
TT
543 retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
544 if (retval)
545 return;
70f4632b 546 if ((ext2fs_dirent_name_len(dirent) != 1) ||
fbc3f901
TT
547 (dirent->name[0] != '.') ||
548 (dirent->inode != pctx->ino) ||
5dd77dbe
TT
549 (rec_len < 12) ||
550 (rec_len % 4) ||
551 (rec_len >= ctx->fs->blocksize - 12))
fbc3f901
TT
552 return;
553
5dd77dbe 554 dirent = (struct ext2_dir_entry *) (buf + rec_len);
8a480350
TT
555 retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
556 if (retval)
557 return;
70f4632b 558 if ((ext2fs_dirent_name_len(dirent) != 2) ||
fbc3f901
TT
559 (dirent->name[0] != '.') ||
560 (dirent->name[1] != '.') ||
5dd77dbe
TT
561 (rec_len < 12) ||
562 (rec_len % 4))
fbc3f901
TT
563 return;
564
042e0719 565isdir:
fbc3f901
TT
566 if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
567 inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
efc6f628
TT
568 e2fsck_write_inode_full(ctx, pctx->ino, inode,
569 EXT2_INODE_SIZE(ctx->fs->super),
fbc3f901
TT
570 "check_is_really_dir");
571 }
572}
573
f404167d
TT
574void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
575 ext2_icount_t *ret)
34b9f796 576{
f954ba01 577 unsigned int threshold;
34b9f796
TT
578 ext2_ino_t num_dirs;
579 errcode_t retval;
f954ba01
TT
580 char *tdb_dir;
581 int enable;
34b9f796
TT
582
583 *ret = 0;
584
585 profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
586 &tdb_dir);
f954ba01
TT
587 profile_get_uint(ctx->profile, "scratch_files",
588 "numdirs_threshold", 0, 0, &threshold);
34b9f796
TT
589 profile_get_boolean(ctx->profile, "scratch_files",
590 "icount", 0, 1, &enable);
591
592 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
593 if (retval)
594 num_dirs = 1024; /* Guess */
595
596 if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
597 (threshold && num_dirs <= threshold))
598 return;
599
600 retval = ext2fs_create_icount_tdb(ctx->fs, tdb_dir, flags, ret);
601 if (retval)
602 *ret = 0;
603}
604
b9cde40d
DW
605static errcode_t recheck_bad_inode_checksum(ext2_filsys fs, ext2_ino_t ino,
606 e2fsck_t ctx,
607 struct problem_context *pctx)
608{
609 errcode_t retval;
610 struct ext2_inode_large inode;
611
612 /*
613 * Reread inode. If we don't see checksum error, then this inode
614 * has been fixed elsewhere.
615 */
616 retval = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)&inode,
617 sizeof(inode));
618 if (retval && retval != EXT2_ET_INODE_CSUM_INVALID)
619 return retval;
620 if (!retval)
621 return 0;
622
623 /*
624 * Checksum still doesn't match. That implies that the inode passes
625 * all the sanity checks, so maybe the checksum is simply corrupt.
626 * See if the user will go for fixing that.
627 */
628 if (!fix_problem(ctx, PR_1_INODE_ONLY_CSUM_INVALID, pctx))
629 return 0;
630
631 retval = ext2fs_write_inode_full(fs, ino, (struct ext2_inode *)&inode,
632 sizeof(inode));
6e3c3b75 633 return retval;
b9cde40d
DW
634}
635
b729b7df
DW
636static void reserve_block_for_root_repair(e2fsck_t ctx)
637{
638 blk64_t blk = 0;
639 errcode_t err;
640 ext2_filsys fs = ctx->fs;
641
642 ctx->root_repair_block = 0;
643 if (ext2fs_test_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO))
644 return;
645
646 err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
647 if (err)
648 return;
649 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
650 ctx->root_repair_block = blk;
651}
652
653static void reserve_block_for_lnf_repair(e2fsck_t ctx)
654{
655 blk64_t blk = 0;
656 errcode_t err;
657 ext2_filsys fs = ctx->fs;
658 static const char name[] = "lost+found";
659 ext2_ino_t ino;
660
661 ctx->lnf_repair_block = 0;
662 if (!ext2fs_lookup(fs, EXT2_ROOT_INO, name, sizeof(name)-1, 0, &ino))
663 return;
664
665 err = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
666 if (err)
667 return;
668 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
669 ctx->lnf_repair_block = blk;
670}
671
6e3c3b75
DW
672static void finish_processing_inode(e2fsck_t ctx, ext2_ino_t ino,
673 struct problem_context *pctx,
674 int failed_csum)
675{
676 if (!failed_csum)
677 return;
678
679 /*
680 * If the inode failed the checksum and the user didn't
681 * clear the inode, test the checksum again -- if it still
682 * fails, ask the user if the checksum should be corrected.
683 */
684 pctx->errcode = recheck_bad_inode_checksum(ctx->fs, ino, ctx, pctx);
685 if (pctx->errcode)
686 ctx->flags |= E2F_FLAG_ABORT;
687}
688#define FINISH_INODE_LOOP(ctx, ino, pctx, failed_csum) \
689 do { \
690 finish_processing_inode((ctx), (ino), (pctx), (failed_csum)); \
691 if ((ctx)->flags & E2F_FLAG_ABORT) \
692 return; \
693 } while (0)
694
08b21301 695void e2fsck_pass1(e2fsck_t ctx)
3839e657 696{
9d1bd3de 697 int i;
31e29a12 698 __u64 max_sizes;
1b6bf175 699 ext2_filsys fs = ctx->fs;
24c91184 700 ext2_ino_t ino = 0;
125f76e7
TT
701 struct ext2_inode *inode = NULL;
702 ext2_inode_scan scan = NULL;
703 char *block_buf = NULL;
8bf191e8 704#ifdef RESOURCE_TRACK
3839e657 705 struct resource_track rtrack;
8bf191e8 706#endif
1e3472c5 707 unsigned char frag, fsize;
21c84b71 708 struct problem_context pctx;
f8188fff 709 struct scan_callback_struct scan_struct;
5dd8f963 710 struct ext2_super_block *sb = ctx->fs->super;
e94bc631 711 const char *old_op;
830b44f4 712 unsigned int save_type;
25fed0fc 713 int imagic_fs, extent_fs, inlinedata_fs;
6f6f567f 714 int low_dtime_check = 1;
cebe48a1 715 int inode_size;
b9cde40d 716 int failed_csum = 0;
efc6f628 717
6d96b00d 718 init_resource_track(&rtrack, ctx->fs->io);
1b6bf175
TT
719 clear_problem_context(&pctx);
720
721 if (!(ctx->options & E2F_OPT_PREEN))
722 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3839e657 723
3214a453
TT
724 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
725 !(ctx->options & E2F_OPT_NO)) {
b7a00563
TT
726 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
727 ctx->dirs_to_hash = 0;
728 }
729
3839e657
TT
730#ifdef MTRACE
731 mtrace_print("Pass 1");
732#endif
733
932a489c
AD
734#define EXT2_BPP(bits) (1ULL << ((bits) - 2))
735
736 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
737 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
738 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
739 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
66df1468 740 max_sizes = (max_sizes * (1UL << i));
7823dd65 741 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
9d1bd3de
TT
742 }
743#undef EXT2_BPP
6fdc7a32 744
6fdc7a32 745 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
15d482ba 746 extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
25fed0fc
ZL
747 inlinedata_fs = (sb->s_feature_incompat &
748 EXT4_FEATURE_INCOMPAT_INLINE_DATA);
6fdc7a32 749
3839e657
TT
750 /*
751 * Allocate bitmaps structures
752 */
830b44f4
TT
753 pctx.errcode = e2fsck_allocate_inode_bitmap(fs, _("in-use inode map"),
754 EXT2FS_BMAP64_RBTREE,
755 "inode_used_map",
756 &ctx->inode_used_map);
1b6bf175
TT
757 if (pctx.errcode) {
758 pctx.num = 1;
759 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
760 ctx->flags |= E2F_FLAG_ABORT;
761 return;
3839e657 762 }
830b44f4
TT
763 pctx.errcode = e2fsck_allocate_inode_bitmap(fs,
764 _("directory inode map"),
765 EXT2FS_BMAP64_AUTODIR,
766 "inode_dir_map", &ctx->inode_dir_map);
1b6bf175
TT
767 if (pctx.errcode) {
768 pctx.num = 2;
769 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
770 ctx->flags |= E2F_FLAG_ABORT;
771 return;
3839e657 772 }
830b44f4
TT
773 pctx.errcode = e2fsck_allocate_inode_bitmap(fs,
774 _("regular file inode map"), EXT2FS_BMAP64_RBTREE,
775 "inode_reg_map", &ctx->inode_reg_map);
aa4115a4
TT
776 if (pctx.errcode) {
777 pctx.num = 6;
778 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
779 ctx->flags |= E2F_FLAG_ABORT;
780 return;
781 }
830b44f4
TT
782 pctx.errcode = e2fsck_allocate_subcluster_bitmap(fs,
783 _("in-use block map"), EXT2FS_BMAP64_RBTREE,
784 "block_found_map", &ctx->block_found_map);
1b6bf175
TT
785 if (pctx.errcode) {
786 pctx.num = 1;
787 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
08b21301
TT
788 ctx->flags |= E2F_FLAG_ABORT;
789 return;
3839e657 790 }
35c8faaf
DW
791 pctx.errcode = e2fsck_allocate_block_bitmap(fs,
792 _("metadata block map"), EXT2FS_BMAP64_RBTREE,
793 "block_metadata_map", &ctx->block_metadata_map);
794 if (pctx.errcode) {
795 pctx.num = 1;
796 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
797 ctx->flags |= E2F_FLAG_ABORT;
798 return;
799 }
34b9f796 800 e2fsck_setup_tdb_icount(ctx, 0, &ctx->inode_link_info);
830b44f4
TT
801 if (!ctx->inode_link_info) {
802 e2fsck_set_bitmap_type(fs, EXT2FS_BMAP64_RBTREE,
803 "inode_link_info", &save_type);
34b9f796
TT
804 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
805 &ctx->inode_link_info);
830b44f4
TT
806 fs->default_bitmap_type = save_type;
807 }
808
1b6bf175
TT
809 if (pctx.errcode) {
810 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
08b21301
TT
811 ctx->flags |= E2F_FLAG_ABORT;
812 return;
21c84b71 813 }
cebe48a1
TT
814 inode_size = EXT2_INODE_SIZE(fs->super);
815 inode = (struct ext2_inode *)
816 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
817
54dc7ca2
TT
818 inodes_to_process = (struct process_inode_block *)
819 e2fsck_allocate_memory(ctx,
820 (ctx->process_inode_size *
821 sizeof(struct process_inode_block)),
822 "array of inodes to process");
3839e657
TT
823 process_inode_count = 0;
824
1b6bf175
TT
825 pctx.errcode = ext2fs_init_dblist(fs, 0);
826 if (pctx.errcode) {
827 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
08b21301 828 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 829 goto endit;
21c84b71 830 }
3839e657 831
9cbfb8d0
TT
832 /*
833 * If the last orphan field is set, clear it, since the pass1
834 * processing will automatically find and clear the orphans.
835 * In the future, we may want to try using the last_orphan
836 * linked list ourselves, but for now, we clear it so that the
837 * ext3 mount code won't get confused.
838 */
839 if (!(ctx->options & E2F_OPT_READONLY)) {
840 if (fs->super->s_last_orphan) {
841 fs->super->s_last_orphan = 0;
842 ext2fs_mark_super_dirty(fs);
843 }
844 }
845
1b6bf175 846 mark_table_blocks(ctx);
44fe08f1
TT
847 pctx.errcode = ext2fs_convert_subcluster_bitmap(fs,
848 &ctx->block_found_map);
849 if (pctx.errcode) {
850 fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
851 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 852 goto endit;
44fe08f1 853 }
54dc7ca2
TT
854 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
855 "block interate buffer");
91db7e20
DW
856 if (EXT2_INODE_SIZE(fs->super) == EXT2_GOOD_OLD_INODE_SIZE)
857 e2fsck_use_inode_shortcuts(ctx, 1);
b4a40883 858 e2fsck_intercept_block_allocations(ctx);
e94bc631 859 old_op = ehandler_operation(_("opening inode scan"));
efc6f628 860 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
1b6bf175 861 &scan);
e94bc631 862 ehandler_operation(old_op);
1b6bf175
TT
863 if (pctx.errcode) {
864 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
08b21301 865 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 866 goto endit;
3839e657 867 }
68d70624
DW
868 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE |
869 EXT2_SF_WARN_GARBAGE_INODES, 0);
cebe48a1 870 ctx->stashed_inode = inode;
f8188fff
TT
871 scan_struct.ctx = ctx;
872 scan_struct.block_buf = block_buf;
873 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
125f76e7
TT
874 if (ctx->progress && ((ctx->progress)(ctx, 1, 0,
875 ctx->fs->group_desc_count)))
876 goto endit;
4147d9f0 877 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
6f6f567f
TT
878 (fs->super->s_mtime < fs->super->s_inodes_count) ||
879 (fs->super->s_mkfs_time &&
880 fs->super->s_mkfs_time < fs->super->s_inodes_count))
881 low_dtime_check = 0;
be93ef0c 882
0f5eba75 883 if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
2fe2d408
AD
884 fs->super->s_mmp_block > fs->super->s_first_data_block &&
885 fs->super->s_mmp_block < ext2fs_blocks_count(fs->super))
0f5eba75
AD
886 ext2fs_mark_block_bitmap2(ctx->block_found_map,
887 fs->super->s_mmp_block);
888
07307114
DW
889 /* Set up ctx->lost_and_found if possible */
890 (void) e2fsck_get_lost_and_found(ctx, 0);
891
d237a78e 892 while (1) {
0f5eba75
AD
893 if (ino % (fs->super->s_inodes_per_group * 4) == 1) {
894 if (e2fsck_mmp_update(fs))
895 fatal_error(ctx, 0);
896 }
e94bc631 897 old_op = ehandler_operation(_("getting next inode from scan"));
efc6f628 898 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
cebe48a1 899 inode, inode_size);
e94bc631 900 ehandler_operation(old_op);
d237a78e
TT
901 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
902 return;
903 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
904 if (!ctx->inode_bb_map)
905 alloc_bb_map(ctx);
c5d2f50d
VAH
906 ext2fs_mark_inode_bitmap2(ctx->inode_bb_map, ino);
907 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
d237a78e
TT
908 continue;
909 }
b9cde40d 910 if (pctx.errcode &&
68d70624
DW
911 pctx.errcode != EXT2_ET_INODE_CSUM_INVALID &&
912 pctx.errcode != EXT2_ET_INODE_IS_GARBAGE) {
d237a78e
TT
913 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
914 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 915 goto endit;
d237a78e
TT
916 }
917 if (!ino)
918 break;
21c84b71 919 pctx.ino = ino;
cebe48a1 920 pctx.inode = inode;
1b6bf175 921 ctx->stashed_ino = ino;
b9cde40d 922
68d70624
DW
923 /* Clear trashed inode? */
924 if (pctx.errcode == EXT2_ET_INODE_IS_GARBAGE &&
925 inode->i_links_count > 0 &&
926 fix_problem(ctx, PR_1_INODE_IS_GARBAGE, &pctx)) {
927 pctx.errcode = 0;
928 e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
b9cde40d 929 }
68d70624 930 failed_csum = pctx.errcode != 0;
b9cde40d 931
cebe48a1 932 if (inode->i_links_count) {
efc6f628 933 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
cebe48a1 934 ino, inode->i_links_count);
1b6bf175 935 if (pctx.errcode) {
cebe48a1 936 pctx.num = inode->i_links_count;
1b6bf175 937 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
08b21301 938 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 939 goto endit;
1b6bf175
TT
940 }
941 }
dfc870c7 942
25fed0fc
ZL
943 /* Test for incorrect inline_data flags settings. */
944 if ((inode->i_flags & EXT4_INLINE_DATA_FL) && !inlinedata_fs &&
945 (ino >= EXT2_FIRST_INODE(fs->super))) {
946 size_t size = 0;
947
948 pctx.errcode = ext2fs_inline_data_size(fs, ino, &size);
949 if (!pctx.errcode && size &&
950 !fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
951 sb->s_feature_incompat |=
952 EXT4_FEATURE_INCOMPAT_INLINE_DATA;
953 ext2fs_mark_super_dirty(fs);
954 inlinedata_fs = 1;
955 } else if (!fix_problem(ctx, PR_1_INLINE_DATA_SET, &pctx)) {
956 e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
6e3c3b75 957 /* skip FINISH_INODE_LOOP */
25fed0fc
ZL
958 continue;
959 }
960 }
961
dfc870c7
ES
962 /*
963 * Test for incorrect extent flag settings.
964 *
965 * On big-endian machines we must be careful:
966 * When the inode is read, the i_block array is not swapped
967 * if the extent flag is set. Therefore if we are testing
968 * for or fixing a wrongly-set flag, we must potentially
969 * (un)swap before testing, or after fixing.
970 */
971
972 /*
973 * In this case the extents flag was set when read, so
974 * extent_header_verify is ok. If the inode is cleared,
975 * no need to swap... so no extra swapping here.
976 */
efc6f628 977 if ((inode->i_flags & EXT4_EXTENTS_FL) && !extent_fs &&
15d482ba
TT
978 (inode->i_links_count || (ino == EXT2_BAD_INO) ||
979 (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO))) {
efc6f628 980 if ((ext2fs_extent_header_verify(inode->i_block,
15d482ba
TT
981 sizeof(inode->i_block)) == 0) &&
982 fix_problem(ctx, PR_1_EXTENT_FEATURE, &pctx)) {
983 sb->s_feature_incompat |= EXT3_FEATURE_INCOMPAT_EXTENTS;
984 ext2fs_mark_super_dirty(fs);
985 extent_fs = 1;
986 } else if (fix_problem(ctx, PR_1_EXTENTS_SET, &pctx)) {
987 clear_inode:
988 e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
989 if (ino == EXT2_BAD_INO)
c5d2f50d 990 ext2fs_mark_inode_bitmap2(ctx->inode_used_map,
15d482ba 991 ino);
6e3c3b75 992 /* skip FINISH_INODE_LOOP */
15d482ba
TT
993 continue;
994 }
995 }
996
dfc870c7
ES
997 /*
998 * For big-endian machines:
999 * If the inode didn't have the extents flag set when it
1000 * was read, then the i_blocks array was swapped. To test
1001 * as an extents header, we must swap it back first.
1002 * IF we then set the extents flag, the entire i_block
1003 * array must be un/re-swapped to make it proper extents data.
1004 */
15d482ba
TT
1005 if (extent_fs && !(inode->i_flags & EXT4_EXTENTS_FL) &&
1006 (inode->i_links_count || (ino == EXT2_BAD_INO) ||
1007 (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO)) &&
1008 (LINUX_S_ISREG(inode->i_mode) ||
dfc870c7
ES
1009 LINUX_S_ISDIR(inode->i_mode))) {
1010 void *ehp;
1011#ifdef WORDS_BIGENDIAN
1012 __u32 tmp_block[EXT2_N_BLOCKS];
1013
1014 for (i = 0; i < EXT2_N_BLOCKS; i++)
1015 tmp_block[i] = ext2fs_swab32(inode->i_block[i]);
1016 ehp = tmp_block;
1017#else
1018 ehp = inode->i_block;
1019#endif
efc6f628 1020 if ((ext2fs_extent_header_verify(ehp,
dfc870c7
ES
1021 sizeof(inode->i_block)) == 0) &&
1022 (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx))) {
15d482ba 1023 inode->i_flags |= EXT4_EXTENTS_FL;
dfc870c7 1024#ifdef WORDS_BIGENDIAN
efc6f628 1025 memcpy(inode->i_block, tmp_block,
dfc870c7
ES
1026 sizeof(inode->i_block));
1027#endif
15d482ba 1028 e2fsck_write_inode(ctx, ino, inode, "pass1");
6e3c3b75 1029 failed_csum = 0;
15d482ba
TT
1030 }
1031 }
1032
3839e657
TT
1033 if (ino == EXT2_BAD_INO) {
1034 struct process_block_struct pb;
efc6f628 1035
492f901e
DW
1036 if ((failed_csum || inode->i_mode || inode->i_uid ||
1037 inode->i_gid || inode->i_links_count ||
1038 (inode->i_flags & EXT4_INLINE_DATA_FL) ||
1039 inode->i_file_acl) &&
96a8afa7
TT
1040 fix_problem(ctx, PR_1_INVALID_BAD_INODE, &pctx)) {
1041 memset(inode, 0, sizeof(struct ext2_inode));
1042 e2fsck_write_inode(ctx, ino, inode,
1043 "clear bad inode");
6e3c3b75 1044 failed_csum = 0;
96a8afa7
TT
1045 }
1046
000ba404
TT
1047 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
1048 &pb.fs_meta_blocks);
1049 if (pctx.errcode) {
1050 pctx.num = 4;
1051 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
1052 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 1053 goto endit;
000ba404 1054 }
3839e657
TT
1055 pb.ino = EXT2_BAD_INO;
1056 pb.num_blocks = pb.last_block = 0;
4dbe79bc 1057 pb.last_db_block = -1;
f3db3566 1058 pb.num_illegal_blocks = 0;
21c84b71 1059 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
000ba404 1060 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
cebe48a1 1061 pb.inode = inode;
21c84b71 1062 pb.pctx = &pctx;
1b6bf175 1063 pb.ctx = ctx;
6dc64392 1064 pctx.errcode = ext2fs_block_iterate3(fs, ino, 0,
1b6bf175 1065 block_buf, process_bad_block, &pb);
000ba404 1066 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
1b6bf175
TT
1067 if (pctx.errcode) {
1068 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
08b21301 1069 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 1070 goto endit;
1b6bf175 1071 }
000ba404
TT
1072 if (pb.bbcheck)
1073 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
1074 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 1075 goto endit;
000ba404 1076 }
c5d2f50d 1077 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
21c84b71 1078 clear_problem_context(&pctx);
6e3c3b75 1079 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
d237a78e 1080 continue;
a9ca2016 1081 } else if (ino == EXT2_ROOT_INO) {
3839e657
TT
1082 /*
1083 * Make sure the root inode is a directory; if
1084 * not, offer to clear it. It will be
1085 * regnerated in pass #3.
1086 */
cebe48a1 1087 if (!LINUX_S_ISDIR(inode->i_mode)) {
15d482ba
TT
1088 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx))
1089 goto clear_inode;
3839e657
TT
1090 }
1091 /*
1092 * If dtime is set, offer to clear it. mke2fs
1093 * version 0.2b created filesystems with the
1094 * dtime field set for the root and lost+found
1095 * directories. We won't worry about
1096 * /lost+found, since that can be regenerated
1097 * easily. But we will fix the root directory
1098 * as a special case.
1099 */
cebe48a1 1100 if (inode->i_dtime && inode->i_links_count) {
1b6bf175 1101 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
cebe48a1
TT
1102 inode->i_dtime = 0;
1103 e2fsck_write_inode(ctx, ino, inode,
f3db3566 1104 "pass1");
6e3c3b75 1105 failed_csum = 0;
21c84b71 1106 }
3839e657 1107 }
a9ca2016 1108 } else if (ino == EXT2_JOURNAL_INO) {
c5d2f50d 1109 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
f18996c8 1110 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
cebe48a1 1111 if (!LINUX_S_ISREG(inode->i_mode) &&
a9ca2016
TT
1112 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
1113 &pctx)) {
cebe48a1
TT
1114 inode->i_mode = LINUX_S_IFREG;
1115 e2fsck_write_inode(ctx, ino, inode,
a9ca2016 1116 "pass1");
6e3c3b75 1117 failed_csum = 0;
a9ca2016 1118 }
f18996c8 1119 check_blocks(ctx, &pctx, block_buf);
6e3c3b75 1120 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
d237a78e 1121 continue;
f18996c8 1122 }
6dc64392 1123 if ((inode->i_links_count ||
cebe48a1 1124 inode->i_blocks || inode->i_block[0]) &&
efc6f628 1125 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
f18996c8 1126 &pctx)) {
cebe48a1 1127 memset(inode, 0, inode_size);
a9ca2016
TT
1128 ext2fs_icount_store(ctx->inode_link_info,
1129 ino, 0);
efc6f628 1130 e2fsck_write_inode_full(ctx, ino, inode,
cebe48a1 1131 inode_size, "pass1");
6e3c3b75 1132 failed_csum = 0;
f18996c8 1133 }
624e4a64
AK
1134 } else if ((ino == EXT4_USR_QUOTA_INO) ||
1135 (ino == EXT4_GRP_QUOTA_INO)) {
1136 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
1137 if ((fs->super->s_feature_ro_compat &
1138 EXT4_FEATURE_RO_COMPAT_QUOTA) &&
9b01faa8
TT
1139 ((fs->super->s_usr_quota_inum == ino) ||
1140 (fs->super->s_grp_quota_inum == ino))) {
624e4a64
AK
1141 if (!LINUX_S_ISREG(inode->i_mode) &&
1142 fix_problem(ctx, PR_1_QUOTA_BAD_MODE,
1143 &pctx)) {
1144 inode->i_mode = LINUX_S_IFREG;
1145 e2fsck_write_inode(ctx, ino, inode,
1146 "pass1");
6e3c3b75 1147 failed_csum = 0;
624e4a64
AK
1148 }
1149 check_blocks(ctx, &pctx, block_buf);
6e3c3b75 1150 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
624e4a64
AK
1151 continue;
1152 }
1153 if ((inode->i_links_count ||
1154 inode->i_blocks || inode->i_block[0]) &&
1155 fix_problem(ctx, PR_1_QUOTA_INODE_NOT_CLEAR,
1156 &pctx)) {
1157 memset(inode, 0, inode_size);
1158 ext2fs_icount_store(ctx->inode_link_info,
1159 ino, 0);
1160 e2fsck_write_inode_full(ctx, ino, inode,
1161 inode_size, "pass1");
6e3c3b75 1162 failed_csum = 0;
624e4a64 1163 }
a9ca2016 1164 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3c7c6d73 1165 problem_t problem = 0;
efc6f628 1166
c5d2f50d 1167 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
53ef44c4 1168 if (ino == EXT2_BOOT_LOADER_INO) {
cebe48a1 1169 if (LINUX_S_ISDIR(inode->i_mode))
b09a4b0c 1170 problem = PR_1_RESERVED_BAD_MODE;
b1f204f7 1171 } else if (ino == EXT2_RESIZE_INO) {
cebe48a1
TT
1172 if (inode->i_mode &&
1173 !LINUX_S_ISREG(inode->i_mode))
b1f204f7 1174 problem = PR_1_RESERVED_BAD_MODE;
53ef44c4 1175 } else {
cebe48a1 1176 if (inode->i_mode != 0)
b09a4b0c 1177 problem = PR_1_RESERVED_BAD_MODE;
b09a4b0c
TT
1178 }
1179 if (problem) {
1180 if (fix_problem(ctx, problem, &pctx)) {
cebe48a1
TT
1181 inode->i_mode = 0;
1182 e2fsck_write_inode(ctx, ino, inode,
50e1e10f 1183 "pass1");
6e3c3b75 1184 failed_csum = 0;
21c84b71 1185 }
50e1e10f 1186 }
1b6bf175 1187 check_blocks(ctx, &pctx, block_buf);
6e3c3b75 1188 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
d237a78e 1189 continue;
3839e657 1190 }
624e4a64 1191
21afac09
TT
1192 /*
1193 * Check for inodes who might have been part of the
1194 * orphaned list linked list. They should have gotten
1195 * dealt with by now, unless the list had somehow been
1196 * corrupted.
efc6f628 1197 *
21afac09
TT
1198 * FIXME: In the future, inodes which are still in use
1199 * (and which are therefore) pending truncation should
1200 * be handled specially. Right now we just clear the
1201 * dtime field, and the normal e2fsck handling of
1202 * inodes where i_size and the inode blocks are
1203 * inconsistent is to fix i_size, instead of releasing
1204 * the extra blocks. This won't catch the inodes that
1205 * was at the end of the orphan list, but it's better
1206 * than nothing. The right answer is that there
1207 * shouldn't be any bugs in the orphan list handling. :-)
1208 */
6f6f567f 1209 if (inode->i_dtime && low_dtime_check &&
cebe48a1 1210 inode->i_dtime < ctx->fs->super->s_inodes_count) {
21afac09 1211 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
cebe48a1 1212 inode->i_dtime = inode->i_links_count ?
1f3ad14a 1213 0 : ctx->now;
cebe48a1 1214 e2fsck_write_inode(ctx, ino, inode,
21afac09 1215 "pass1");
6e3c3b75 1216 failed_csum = 0;
21afac09
TT
1217 }
1218 }
efc6f628 1219
3839e657
TT
1220 /*
1221 * This code assumes that deleted inodes have
efc6f628 1222 * i_links_count set to 0.
3839e657 1223 */
cebe48a1
TT
1224 if (!inode->i_links_count) {
1225 if (!inode->i_dtime && inode->i_mode) {
1b6bf175 1226 if (fix_problem(ctx,
21c84b71 1227 PR_1_ZERO_DTIME, &pctx)) {
1f3ad14a 1228 inode->i_dtime = ctx->now;
cebe48a1 1229 e2fsck_write_inode(ctx, ino, inode,
f3db3566 1230 "pass1");
6e3c3b75 1231 failed_csum = 0;
21c84b71 1232 }
3839e657 1233 }
6e3c3b75 1234 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
d237a78e 1235 continue;
3839e657
TT
1236 }
1237 /*
1e3472c5 1238 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3839e657 1239 * deleted files. Oops.
1e3472c5
TT
1240 *
1241 * Since all new ext2 implementations get this right,
1242 * we now assume that the case of non-zero
1243 * i_links_count and non-zero dtime means that we
1244 * should keep the file, not delete it.
efc6f628 1245 *
3839e657 1246 */
cebe48a1 1247 if (inode->i_dtime) {
1b6bf175 1248 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
cebe48a1
TT
1249 inode->i_dtime = 0;
1250 e2fsck_write_inode(ctx, ino, inode, "pass1");
6e3c3b75 1251 failed_csum = 0;
21c84b71 1252 }
3839e657 1253 }
efc6f628 1254
c5d2f50d 1255 ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
1e3472c5 1256 switch (fs->super->s_creator_os) {
1e3472c5 1257 case EXT2_OS_HURD:
cebe48a1
TT
1258 frag = inode->osd2.hurd2.h_i_frag;
1259 fsize = inode->osd2.hurd2.h_i_fsize;
1e3472c5 1260 break;
1e3472c5
TT
1261 default:
1262 frag = fsize = 0;
1263 }
efc6f628 1264
cebe48a1
TT
1265 if (inode->i_faddr || frag || fsize ||
1266 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
fdbdea09 1267 mark_inode_bad(ctx, ino);
911ec626
TT
1268 if (!(fs->super->s_feature_incompat &
1269 EXT4_FEATURE_INCOMPAT_64BIT) &&
1270 inode->osd2.linux2.l_i_file_acl_high != 0)
1271 mark_inode_bad(ctx, ino);
5d17119d 1272 if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
efc6f628 1273 !(fs->super->s_feature_ro_compat &
5d17119d
TT
1274 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
1275 (inode->osd2.linux2.l_i_blocks_hi != 0))
1276 mark_inode_bad(ctx, ino);
cebe48a1 1277 if (inode->i_flags & EXT2_IMAGIC_FL) {
6fdc7a32
TT
1278 if (imagic_fs) {
1279 if (!ctx->inode_imagic_map)
1280 alloc_imagic_map(ctx);
c5d2f50d 1281 ext2fs_mark_inode_bitmap2(ctx->inode_imagic_map,
6fdc7a32
TT
1282 ino);
1283 } else {
1284 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
cebe48a1 1285 inode->i_flags &= ~EXT2_IMAGIC_FL;
6fdc7a32 1286 e2fsck_write_inode(ctx, ino,
cebe48a1 1287 inode, "pass1");
6e3c3b75 1288 failed_csum = 0;
6fdc7a32
TT
1289 }
1290 }
aa4115a4 1291 }
cebe48a1
TT
1292
1293 check_inode_extra_space(ctx, &pctx);
fbc3f901 1294 check_is_really_dir(ctx, &pctx, block_buf);
cebe48a1 1295
dfc870c7 1296 /*
0c80c44b 1297 * ext2fs_inode_has_valid_blocks2 does not actually look
dfc870c7
ES
1298 * at i_block[] values, so not endian-sensitive here.
1299 */
cb23cad5
TT
1300 if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL) &&
1301 LINUX_S_ISLNK(inode->i_mode) &&
0c80c44b 1302 !ext2fs_inode_has_valid_blocks2(fs, inode) &&
cb23cad5
TT
1303 fix_problem(ctx, PR_1_FAST_SYMLINK_EXTENT_FL, &pctx)) {
1304 inode->i_flags &= ~EXT4_EXTENTS_FL;
1305 e2fsck_write_inode(ctx, ino, inode, "pass1");
6e3c3b75 1306 failed_csum = 0;
cb23cad5
TT
1307 }
1308
cebe48a1 1309 if (LINUX_S_ISDIR(inode->i_mode)) {
c5d2f50d 1310 ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
08b21301 1311 e2fsck_add_dir_info(ctx, ino, 0);
1b6bf175 1312 ctx->fs_directory_count++;
cebe48a1 1313 } else if (LINUX_S_ISREG (inode->i_mode)) {
c5d2f50d 1314 ext2fs_mark_inode_bitmap2(ctx->inode_reg_map, ino);
1b6bf175 1315 ctx->fs_regular_count++;
cebe48a1
TT
1316 } else if (LINUX_S_ISCHR (inode->i_mode) &&
1317 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 1318 check_immutable(ctx, &pctx);
d647a1ea 1319 check_size(ctx, &pctx);
1b6bf175 1320 ctx->fs_chardev_count++;
cebe48a1
TT
1321 } else if (LINUX_S_ISBLK (inode->i_mode) &&
1322 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 1323 check_immutable(ctx, &pctx);
d647a1ea 1324 check_size(ctx, &pctx);
1b6bf175 1325 ctx->fs_blockdev_count++;
cebe48a1 1326 } else if (LINUX_S_ISLNK (inode->i_mode) &&
efc6f628 1327 e2fsck_pass1_check_symlink(fs, ino, inode,
7cadc577 1328 block_buf)) {
fd77b2c7 1329 check_immutable(ctx, &pctx);
1b6bf175 1330 ctx->fs_symlinks_count++;
f9f8fded 1331 if (inode->i_flags & EXT4_INLINE_DATA_FL) {
6e3c3b75 1332 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
f9f8fded
ZL
1333 continue;
1334 } else if (ext2fs_inode_data_blocks(fs, inode) == 0) {
1b6bf175 1335 ctx->fs_fast_symlinks_count++;
0684a4f3 1336 check_blocks(ctx, &pctx, block_buf);
6e3c3b75 1337 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
d237a78e 1338 continue;
21c84b71 1339 }
3839e657 1340 }
cebe48a1
TT
1341 else if (LINUX_S_ISFIFO (inode->i_mode) &&
1342 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 1343 check_immutable(ctx, &pctx);
d647a1ea 1344 check_size(ctx, &pctx);
1b6bf175 1345 ctx->fs_fifo_count++;
cebe48a1
TT
1346 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
1347 e2fsck_pass1_check_device_inode(fs, inode)) {
6fdc7a32 1348 check_immutable(ctx, &pctx);
d647a1ea
TT
1349 check_size(ctx, &pctx);
1350 ctx->fs_sockets_count++;
fdbdea09
TT
1351 } else
1352 mark_inode_bad(ctx, ino);
042e0719
ZL
1353 if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
1354 !(inode->i_flags & EXT4_INLINE_DATA_FL)) {
8da6d1a1
TT
1355 if (inode->i_block[EXT2_IND_BLOCK])
1356 ctx->fs_ind_count++;
1357 if (inode->i_block[EXT2_DIND_BLOCK])
1358 ctx->fs_dind_count++;
1359 if (inode->i_block[EXT2_TIND_BLOCK])
1360 ctx->fs_tind_count++;
1361 }
15d482ba 1362 if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
042e0719 1363 !(inode->i_flags & EXT4_INLINE_DATA_FL) &&
15d482ba
TT
1364 (inode->i_block[EXT2_IND_BLOCK] ||
1365 inode->i_block[EXT2_DIND_BLOCK] ||
1366 inode->i_block[EXT2_TIND_BLOCK] ||
0c80c44b 1367 ext2fs_file_acl_block(fs, inode))) {
3839e657 1368 inodes_to_process[process_inode_count].ino = ino;
cebe48a1 1369 inodes_to_process[process_inode_count].inode = *inode;
3839e657 1370 process_inode_count++;
f3db3566 1371 } else
1b6bf175 1372 check_blocks(ctx, &pctx, block_buf);
3839e657 1373
6e3c3b75 1374 FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum);
b9cde40d 1375
a02ce9df 1376 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
125f76e7 1377 goto endit;
08b21301
TT
1378
1379 if (process_inode_count >= ctx->process_inode_size) {
1b6bf175 1380 process_inodes(ctx, block_buf);
08b21301 1381
a02ce9df 1382 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
125f76e7 1383 goto endit;
08b21301 1384 }
3839e657 1385 }
1b6bf175 1386 process_inodes(ctx, block_buf);
3839e657 1387 ext2fs_close_inode_scan(scan);
125f76e7 1388 scan = NULL;
3839e657 1389
b729b7df
DW
1390 reserve_block_for_root_repair(ctx);
1391 reserve_block_for_lnf_repair(ctx);
1392
e8a3ee62
TT
1393 /*
1394 * If any extended attribute blocks' reference counts need to
1395 * be adjusted, either up (ctx->refcount_extra), or down
1396 * (ctx->refcount), then fix them.
1397 */
1398 if (ctx->refcount) {
1399 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
1400 ea_refcount_free(ctx->refcount);
1401 ctx->refcount = 0;
1402 }
1403 if (ctx->refcount_extra) {
1404 adjust_extattr_refcount(ctx, ctx->refcount_extra,
1405 block_buf, +1);
1406 ea_refcount_free(ctx->refcount_extra);
1407 ctx->refcount_extra = 0;
1408 }
efc6f628 1409
1b6bf175
TT
1410 if (ctx->invalid_bitmaps)
1411 handle_fs_bad_blocks(ctx);
f3db3566 1412
24ceb248
TT
1413 /* We don't need the block_ea_map any more */
1414 if (ctx->block_ea_map) {
1415 ext2fs_free_block_bitmap(ctx->block_ea_map);
1416 ctx->block_ea_map = 0;
1417 }
1418
c3ffaf83 1419 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
c3ffaf83
TT
1420 clear_problem_context(&pctx);
1421 pctx.errcode = ext2fs_create_resize_inode(fs);
1422 if (pctx.errcode) {
a6217f5a
TT
1423 if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
1424 &pctx)) {
1425 ctx->flags |= E2F_FLAG_ABORT;
125f76e7 1426 goto endit;
a6217f5a
TT
1427 }
1428 pctx.errcode = 0;
1429 }
1430 if (!pctx.errcode) {
1431 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
1432 "recreate inode");
1433 inode->i_mtime = ctx->now;
1434 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
1435 "recreate inode");
c3ffaf83 1436 }
c3ffaf83
TT
1437 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
1438 }
efc6f628 1439
08b21301 1440 if (ctx->flags & E2F_FLAG_RESTART) {
aa4115a4
TT
1441 /*
1442 * Only the master copy of the superblock and block
1443 * group descriptors are going to be written during a
1444 * restart, so set the superblock to be used to be the
1445 * master superblock.
1446 */
1447 ctx->use_superblock = 0;
f3db3566
TT
1448 unwind_pass1(fs);
1449 goto endit;
1450 }
1451
1b6bf175
TT
1452 if (ctx->block_dup_map) {
1453 if (ctx->options & E2F_OPT_PREEN) {
1454 clear_problem_context(&pctx);
1455 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3839e657 1456 }
08b21301 1457 e2fsck_pass1_dupblocks(ctx, block_buf);
3839e657 1458 }
c4e3d3f3 1459 ext2fs_free_mem(&inodes_to_process);
f3db3566 1460endit:
e72a9ba3 1461 e2fsck_use_inode_shortcuts(ctx, 0);
efc6f628 1462
125f76e7
TT
1463 if (scan)
1464 ext2fs_close_inode_scan(scan);
1465 if (block_buf)
1466 ext2fs_free_mem(&block_buf);
1467 if (inode)
1468 ext2fs_free_mem(&inode);
21c84b71 1469
82372e32
TT
1470 /*
1471 * The l+f inode may have been cleared, so zap it now and
1472 * later passes will recalculate it if necessary
1473 */
1474 ctx->lost_and_found = 0;
1475
125f76e7
TT
1476 if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
1477 print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
3839e657 1478}
6e3c3b75 1479#undef FINISH_INODE_LOOP
3839e657 1480
f3db3566
TT
1481/*
1482 * When the inode_scan routines call this callback at the end of the
1483 * glock group, call process_inodes.
1484 */
efc6f628 1485static errcode_t scan_callback(ext2_filsys fs,
54434927 1486 ext2_inode_scan scan EXT2FS_ATTR((unused)),
54dc7ca2 1487 dgrp_t group, void * priv_data)
f3db3566 1488{
54dc7ca2 1489 struct scan_callback_struct *scan_struct;
f8188fff
TT
1490 e2fsck_t ctx;
1491
54dc7ca2 1492 scan_struct = (struct scan_callback_struct *) priv_data;
f8188fff 1493 ctx = scan_struct->ctx;
efc6f628 1494
54dc7ca2 1495 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
f8188fff
TT
1496
1497 if (ctx->progress)
a02ce9df
TT
1498 if ((ctx->progress)(ctx, 1, group+1,
1499 ctx->fs->group_desc_count))
1500 return EXT2_ET_CANCEL_REQUESTED;
f8188fff 1501
f3db3566
TT
1502 return 0;
1503}
1504
3839e657
TT
1505/*
1506 * Process the inodes in the "inodes to process" list.
1507 */
1b6bf175 1508static void process_inodes(e2fsck_t ctx, char *block_buf)
3839e657
TT
1509{
1510 int i;
1511 struct ext2_inode *old_stashed_inode;
86c627ec 1512 ext2_ino_t old_stashed_ino;
3839e657
TT
1513 const char *old_operation;
1514 char buf[80];
21c84b71 1515 struct problem_context pctx;
efc6f628 1516
3839e657 1517#if 0
f3db3566 1518 printf("begin process_inodes: ");
3839e657 1519#endif
86a63e92
TT
1520 if (process_inode_count == 0)
1521 return;
3839e657 1522 old_operation = ehandler_operation(0);
1b6bf175
TT
1523 old_stashed_inode = ctx->stashed_inode;
1524 old_stashed_ino = ctx->stashed_ino;
3839e657
TT
1525 qsort(inodes_to_process, process_inode_count,
1526 sizeof(struct process_inode_block), process_inode_cmp);
21c84b71 1527 clear_problem_context(&pctx);
3839e657 1528 for (i=0; i < process_inode_count; i++) {
1b6bf175
TT
1529 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
1530 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
efc6f628 1531
3839e657 1532#if 0
21c84b71 1533 printf("%u ", pctx.ino);
3839e657 1534#endif
86c627ec 1535 sprintf(buf, _("reading indirect blocks of inode %u"),
0c4a0726 1536 pctx.ino);
3839e657 1537 ehandler_operation(buf);
1b6bf175 1538 check_blocks(ctx, &pctx, block_buf);
a02ce9df 1539 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2df1f6aa 1540 break;
3839e657 1541 }
1b6bf175
TT
1542 ctx->stashed_inode = old_stashed_inode;
1543 ctx->stashed_ino = old_stashed_ino;
3839e657
TT
1544 process_inode_count = 0;
1545#if 0
f3db3566 1546 printf("end process inodes\n");
3839e657
TT
1547#endif
1548 ehandler_operation(old_operation);
1549}
1550
4c77fe50 1551static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
3839e657
TT
1552{
1553 const struct process_inode_block *ib_a =
1554 (const struct process_inode_block *) a;
1555 const struct process_inode_block *ib_b =
1556 (const struct process_inode_block *) b;
b5acdb6a 1557 int ret;
efc6f628 1558
b5acdb6a
TT
1559 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
1560 ib_b->inode.i_block[EXT2_IND_BLOCK]);
1561 if (ret == 0)
0c80c44b
TT
1562 /*
1563 * We only call process_inodes() for non-extent
1564 * inodes, so it's OK to pass NULL to
1565 * ext2fs_file_acl_block() here.
1566 */
1567 ret = ext2fs_file_acl_block(0, &(ib_a->inode)) -
1568 ext2fs_file_acl_block(0, &(ib_b->inode));
0eeec8ac
TT
1569 if (ret == 0)
1570 ret = ib_a->ino - ib_b->ino;
b5acdb6a 1571 return ret;
3839e657
TT
1572}
1573
3839e657 1574/*
fdbdea09 1575 * Mark an inode as being bad in some what
3839e657 1576 */
fdbdea09 1577static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3839e657 1578{
1b6bf175 1579 struct problem_context pctx;
fdbdea09
TT
1580
1581 if (!ctx->inode_bad_map) {
1582 clear_problem_context(&pctx);
efc6f628 1583
830b44f4
TT
1584 pctx.errcode = e2fsck_allocate_inode_bitmap(ctx->fs,
1585 _("bad inode map"), EXT2FS_BMAP64_RBTREE,
1586 "inode_bad_map", &ctx->inode_bad_map);
fdbdea09
TT
1587 if (pctx.errcode) {
1588 pctx.num = 3;
1589 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1590 /* Should never get here */
1591 ctx->flags |= E2F_FLAG_ABORT;
1592 return;
1593 }
3839e657 1594 }
c5d2f50d 1595 ext2fs_mark_inode_bitmap2(ctx->inode_bad_map, ino);
3839e657
TT
1596}
1597
fdbdea09 1598
21c84b71
TT
1599/*
1600 * This procedure will allocate the inode "bb" (badblock) map table
1601 */
1b6bf175 1602static void alloc_bb_map(e2fsck_t ctx)
21c84b71 1603{
1b6bf175 1604 struct problem_context pctx;
efc6f628 1605
1b6bf175 1606 clear_problem_context(&pctx);
830b44f4
TT
1607 pctx.errcode = e2fsck_allocate_inode_bitmap(ctx->fs,
1608 _("inode in bad block map"), EXT2FS_BMAP64_RBTREE,
1609 "inode_bb_map", &ctx->inode_bb_map);
1b6bf175
TT
1610 if (pctx.errcode) {
1611 pctx.num = 4;
1612 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
1613 /* Should never get here */
1614 ctx->flags |= E2F_FLAG_ABORT;
1615 return;
21c84b71
TT
1616 }
1617}
1618
aa4115a4
TT
1619/*
1620 * This procedure will allocate the inode imagic table
1621 */
1622static void alloc_imagic_map(e2fsck_t ctx)
1623{
1624 struct problem_context pctx;
efc6f628 1625
aa4115a4 1626 clear_problem_context(&pctx);
830b44f4
TT
1627 pctx.errcode = e2fsck_allocate_inode_bitmap(ctx->fs,
1628 _("imagic inode map"), EXT2FS_BMAP64_RBTREE,
1629 "inode_imagic_map", &ctx->inode_imagic_map);
aa4115a4
TT
1630 if (pctx.errcode) {
1631 pctx.num = 5;
1632 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1633 /* Should never get here */
1634 ctx->flags |= E2F_FLAG_ABORT;
1635 return;
1636 }
1637}
1638
3839e657
TT
1639/*
1640 * Marks a block as in use, setting the dup_map if it's been set
1641 * already. Called by process_block and process_bad_block.
50e1e10f
TT
1642 *
1643 * WARNING: Assumes checks have already been done to make sure block
1644 * is valid. This is true in both process_block and process_bad_block.
3839e657 1645 */
6dc64392 1646static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
3839e657 1647{
1b6bf175 1648 struct problem_context pctx;
efc6f628 1649
1b6bf175 1650 clear_problem_context(&pctx);
efc6f628 1651
c5d2f50d 1652 if (ext2fs_fast_test_block_bitmap2(ctx->block_found_map, block)) {
1b6bf175 1653 if (!ctx->block_dup_map) {
830b44f4
TT
1654 pctx.errcode = e2fsck_allocate_block_bitmap(ctx->fs,
1655 _("multiply claimed block map"),
1656 EXT2FS_BMAP64_RBTREE, "block_dup_map",
1657 &ctx->block_dup_map);
1b6bf175
TT
1658 if (pctx.errcode) {
1659 pctx.num = 3;
efc6f628 1660 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
1b6bf175 1661 &pctx);
08b21301
TT
1662 /* Should never get here */
1663 ctx->flags |= E2F_FLAG_ABORT;
1664 return;
3839e657
TT
1665 }
1666 }
c5d2f50d 1667 ext2fs_fast_mark_block_bitmap2(ctx->block_dup_map, block);
3839e657 1668 } else {
c5d2f50d 1669 ext2fs_fast_mark_block_bitmap2(ctx->block_found_map, block);
3839e657
TT
1670 }
1671}
1672
2ae49fd0
TT
1673static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
1674 unsigned int num)
1675{
1676 if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
1677 ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
1678 else
1679 while (num--)
1680 mark_block_used(ctx, block++);
1681}
1682
e8a3ee62
TT
1683/*
1684 * Adjust the extended attribute block's reference counts at the end
1685 * of pass 1, either by subtracting out references for EA blocks that
1686 * are still referenced in ctx->refcount, or by adding references for
1687 * EA blocks that had extra references as accounted for in
1688 * ctx->refcount_extra.
1689 */
efc6f628 1690static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
e8a3ee62
TT
1691 char *block_buf, int adjust_sign)
1692{
1693 struct ext2_ext_attr_header *header;
1694 struct problem_context pctx;
1695 ext2_filsys fs = ctx->fs;
6dc64392 1696 blk64_t blk;
e8a3ee62
TT
1697 __u32 should_be;
1698 int count;
1699
1700 clear_problem_context(&pctx);
efc6f628 1701
e8a3ee62
TT
1702 ea_refcount_intr_begin(refcount);
1703 while (1) {
1704 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
1705 break;
1706 pctx.blk = blk;
39f5659a
DW
1707 pctx.errcode = ext2fs_read_ext_attr3(fs, blk, block_buf,
1708 pctx.ino);
e8a3ee62
TT
1709 if (pctx.errcode) {
1710 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
1711 return;
1712 }
1713 header = (struct ext2_ext_attr_header *) block_buf;
1714 pctx.blkcount = header->h_refcount;
1715 should_be = header->h_refcount + adjust_sign * count;
1716 pctx.num = should_be;
1717 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
1718 header->h_refcount = should_be;
39f5659a
DW
1719 pctx.errcode = ext2fs_write_ext_attr3(fs, blk,
1720 block_buf,
1721 pctx.ino);
e8a3ee62 1722 if (pctx.errcode) {
a6217f5a
TT
1723 fix_problem(ctx, PR_1_EXTATTR_WRITE_ABORT,
1724 &pctx);
e8a3ee62
TT
1725 continue;
1726 }
1727 }
1728 }
1729}
1730
342d847d
TT
1731/*
1732 * Handle processing the extended attribute blocks
1733 */
1734static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
1735 char *block_buf)
1736{
1737 ext2_filsys fs = ctx->fs;
1738 ext2_ino_t ino = pctx->ino;
1739 struct ext2_inode *inode = pctx->inode;
6dc64392 1740 blk64_t blk;
55fd07ed 1741 char * end;
e8a3ee62 1742 struct ext2_ext_attr_header *header;
55fd07ed 1743 struct ext2_ext_attr_entry *entry;
342d847d 1744 int count;
86bc90f4 1745 region_t region = 0;
5e07cb28 1746 int failed_csum = 0;
5469d767 1747
0c80c44b 1748 blk = ext2fs_file_acl_block(fs, inode);
342d847d
TT
1749 if (blk == 0)
1750 return 0;
1751
1752 /*
1753 * If the Extended attribute flag isn't set, then a non-zero
1754 * file acl means that the inode is corrupted.
1755 *
1756 * Or if the extended attribute block is an invalid block,
1757 * then the inode is also corrupted.
1758 */
1759 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
1760 (blk < fs->super->s_first_data_block) ||
4efbac6f 1761 (blk >= ext2fs_blocks_count(fs->super))) {
342d847d
TT
1762 mark_inode_bad(ctx, ino);
1763 return 0;
1764 }
1765
1766 /* If ea bitmap hasn't been allocated, create it */
1767 if (!ctx->block_ea_map) {
830b44f4
TT
1768 pctx->errcode = e2fsck_allocate_block_bitmap(fs,
1769 _("ext attr block map"),
1770 EXT2FS_BMAP64_RBTREE, "block_ea_map",
1771 &ctx->block_ea_map);
342d847d
TT
1772 if (pctx->errcode) {
1773 pctx->num = 2;
1774 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
1775 ctx->flags |= E2F_FLAG_ABORT;
1776 return 0;
1777 }
1778 }
1779
1780 /* Create the EA refcount structure if necessary */
1781 if (!ctx->refcount) {
1782 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
1783 if (pctx->errcode) {
1784 pctx->num = 1;
1785 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1786 ctx->flags |= E2F_FLAG_ABORT;
1787 return 0;
1788 }
1789 }
1790
b5acdb6a
TT
1791#if 0
1792 /* Debugging text */
1793 printf("Inode %u has EA block %u\n", ino, blk);
1794#endif
1795
342d847d 1796 /* Have we seen this EA block before? */
c5d2f50d 1797 if (ext2fs_fast_test_block_bitmap2(ctx->block_ea_map, blk)) {
342d847d
TT
1798 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
1799 return 1;
1800 /* Ooops, this EA was referenced more than it stated */
1801 if (!ctx->refcount_extra) {
1802 pctx->errcode = ea_refcount_create(0,
1803 &ctx->refcount_extra);
1804 if (pctx->errcode) {
1805 pctx->num = 2;
1806 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1807 ctx->flags |= E2F_FLAG_ABORT;
55fd07ed 1808 return 0;
342d847d
TT
1809 }
1810 }
1811 ea_refcount_increment(ctx->refcount_extra, blk, 0);
1812 return 1;
1813 }
5469d767 1814
342d847d
TT
1815 /*
1816 * OK, we haven't seen this EA block yet. So we need to
1817 * validate it
1818 */
1819 pctx->blk = blk;
39f5659a 1820 pctx->errcode = ext2fs_read_ext_attr3(fs, blk, block_buf, pctx->ino);
5e07cb28 1821 if (pctx->errcode == EXT2_ET_EXT_ATTR_CSUM_INVALID) {
5b9cbd76 1822 pctx->errcode = 0;
5e07cb28 1823 failed_csum = 1;
5b9cbd76
DW
1824 } else if (pctx->errcode == EXT2_ET_BAD_EA_HEADER)
1825 pctx->errcode = 0;
1826
1827 if (pctx->errcode &&
1828 fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx)) {
1829 pctx->errcode = 0;
342d847d 1830 goto clear_extattr;
5b9cbd76 1831 }
342d847d 1832 header = (struct ext2_ext_attr_header *) block_buf;
0c80c44b 1833 pctx->blk = ext2fs_file_acl_block(fs, inode);
0684a4f3
TT
1834 if (((ctx->ext_attr_ver == 1) &&
1835 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
1836 ((ctx->ext_attr_ver == 2) &&
1837 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
1838 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
1839 goto clear_extattr;
1840 }
0d63467d 1841
55fd07ed
TT
1842 if (header->h_blocks != 1) {
1843 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
1844 goto clear_extattr;
1845 }
1846
5b9cbd76
DW
1847 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
1848 goto clear_extattr;
1849
55fd07ed
TT
1850 region = region_create(0, fs->blocksize);
1851 if (!region) {
a6217f5a 1852 fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
55fd07ed
TT
1853 ctx->flags |= E2F_FLAG_ABORT;
1854 return 0;
1855 }
1856 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
1857 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
342d847d
TT
1858 goto clear_extattr;
1859 }
5469d767 1860
55fd07ed
TT
1861 entry = (struct ext2_ext_attr_entry *)(header+1);
1862 end = block_buf + fs->blocksize;
1863 while ((char *)entry < end && *(__u32 *)entry) {
fefaef39
AD
1864 __u32 hash;
1865
55fd07ed
TT
1866 if (region_allocate(region, (char *)entry - (char *)header,
1867 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
1868 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1869 goto clear_extattr;
fefaef39 1870 break;
55fd07ed 1871 }
0684a4f3 1872 if ((ctx->ext_attr_ver == 1 &&
0d63467d 1873 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
0684a4f3 1874 (ctx->ext_attr_ver == 2 &&
0d63467d 1875 entry->e_name_index == 0)) {
55fd07ed
TT
1876 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
1877 goto clear_extattr;
fefaef39 1878 break;
55fd07ed
TT
1879 }
1880 if (entry->e_value_block != 0) {
1881 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1882 goto clear_extattr;
1883 }
a34c6ffd
AD
1884 if (entry->e_value_offs + entry->e_value_size > fs->blocksize) {
1885 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1886 goto clear_extattr;
1887 break;
1888 }
14fe1c33
TT
1889 if (entry->e_value_size &&
1890 region_allocate(region, entry->e_value_offs,
1891 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
55fd07ed
TT
1892 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1893 goto clear_extattr;
1894 }
fefaef39
AD
1895
1896 hash = ext2fs_ext_attr_hash_entry(entry, block_buf +
1897 entry->e_value_offs);
1898
1899 if (entry->e_hash != hash) {
1900 pctx->num = entry->e_hash;
1901 if (fix_problem(ctx, PR_1_ATTR_HASH, pctx))
1902 goto clear_extattr;
1903 entry->e_hash = hash;
1904 }
1905
55fd07ed
TT
1906 entry = EXT2_EXT_ATTR_NEXT(entry);
1907 }
1908 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
1909 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1910 goto clear_extattr;
1911 }
1912 region_free(region);
342d847d 1913
5e07cb28
DW
1914 /*
1915 * We only get here if there was no other errors that were fixed.
1916 * If there was a checksum fail, ask to correct it.
1917 */
1918 if (failed_csum &&
1919 fix_problem(ctx, PR_1_EA_BLOCK_ONLY_CSUM_INVALID, pctx)) {
1920 pctx->errcode = ext2fs_write_ext_attr3(fs, blk, block_buf,
1921 pctx->ino);
1922 if (pctx->errcode)
1923 return 0;
1924 }
1925
342d847d
TT
1926 count = header->h_refcount - 1;
1927 if (count)
1928 ea_refcount_store(ctx->refcount, blk, count);
1929 mark_block_used(ctx, blk);
c5d2f50d 1930 ext2fs_fast_mark_block_bitmap2(ctx->block_ea_map, blk);
342d847d
TT
1931 return 1;
1932
1933clear_extattr:
5469d767
BB
1934 if (region)
1935 region_free(region);
0c80c44b 1936 ext2fs_file_acl_block_set(fs, inode, 0);
342d847d
TT
1937 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
1938 return 0;
1939}
1940
503f9e7f
TT
1941/* Returns 1 if bad htree, 0 if OK */
1942static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
15d482ba 1943 ext2_ino_t ino, struct ext2_inode *inode,
503f9e7f
TT
1944 char *block_buf)
1945{
1946 struct ext2_dx_root_info *root;
1947 ext2_filsys fs = ctx->fs;
1948 errcode_t retval;
6dc64392 1949 blk64_t blk;
503f9e7f
TT
1950
1951 if ((!LINUX_S_ISDIR(inode->i_mode) &&
1952 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
1953 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
1954 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
1955 return 1;
1956
6dc64392 1957 pctx->errcode = ext2fs_bmap2(fs, ino, inode, 0, 0, 0, 0, &blk);
15d482ba
TT
1958
1959 if ((pctx->errcode) ||
1960 (blk == 0) ||
1961 (blk < fs->super->s_first_data_block) ||
4efbac6f 1962 (blk >= ext2fs_blocks_count(fs->super))) {
15d482ba
TT
1963 if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1964 return 1;
1965 else
1966 return 0;
1967 }
503f9e7f 1968
24a117ab 1969 retval = io_channel_read_blk64(fs->io, blk, 1, block_buf);
503f9e7f
TT
1970 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1971 return 1;
efc6f628 1972
503f9e7f
TT
1973 /* XXX should check that beginning matches a directory */
1974 root = (struct ext2_dx_root_info *) (block_buf + 24);
1975
1976 if ((root->reserved_zero || root->info_length < 8) &&
1977 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1978 return 1;
1979
1980 pctx->num = root->hash_version;
1981 if ((root->hash_version != EXT2_HASH_LEGACY) &&
1982 (root->hash_version != EXT2_HASH_HALF_MD4) &&
f044b4d8 1983 (root->hash_version != EXT2_HASH_TEA) &&
503f9e7f
TT
1984 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
1985 return 1;
efc6f628 1986
503f9e7f
TT
1987 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
1988 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
1989 return 1;
1990
1991 pctx->num = root->indirect_levels;
1992 if ((root->indirect_levels > 1) &&
1993 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
1994 return 1;
efc6f628 1995
503f9e7f
TT
1996 return 0;
1997}
342d847d 1998
e3df15ab
TT
1999void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
2000 struct ext2_inode *inode, int restart_flag,
2001 const char *source)
2002{
15d482ba 2003 inode->i_flags = 0;
e3df15ab
TT
2004 inode->i_links_count = 0;
2005 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
2006 inode->i_dtime = ctx->now;
2007
c5d2f50d
VAH
2008 ext2fs_unmark_inode_bitmap2(ctx->inode_dir_map, ino);
2009 ext2fs_unmark_inode_bitmap2(ctx->inode_used_map, ino);
e3df15ab 2010 if (ctx->inode_reg_map)
c5d2f50d 2011 ext2fs_unmark_inode_bitmap2(ctx->inode_reg_map, ino);
e3df15ab 2012 if (ctx->inode_bad_map)
c5d2f50d 2013 ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino);
e3df15ab
TT
2014
2015 /*
2016 * If the inode was partially accounted for before processing
2017 * was aborted, we need to restart the pass 1 scan.
2018 */
2019 ctx->flags |= restart_flag;
2020
96a8afa7
TT
2021 if (ino == EXT2_BAD_INO)
2022 memset(inode, 0, sizeof(struct ext2_inode));
2023
e3df15ab
TT
2024 e2fsck_write_inode(ctx, ino, inode, source);
2025}
2026
9a1d614d
DW
2027/*
2028 * Use the multiple-blocks reclamation code to fix alignment problems in
2029 * a bigalloc filesystem. We want a logical cluster to map to *only* one
2030 * physical cluster, and we want the block offsets within that cluster to
2031 * line up.
2032 */
2033static int has_unaligned_cluster_map(e2fsck_t ctx,
2034 blk64_t last_pblk, e2_blkcnt_t last_lblk,
2035 blk64_t pblk, blk64_t lblk)
2036{
2037 blk64_t cluster_mask;
2038
2039 if (!ctx->fs->cluster_ratio_bits)
2040 return 0;
2041 cluster_mask = EXT2FS_CLUSTER_MASK(ctx->fs);
2042
2043 /*
2044 * If the block in the logical cluster doesn't align with the block in
2045 * the physical cluster...
2046 */
2047 if ((lblk & cluster_mask) != (pblk & cluster_mask))
2048 return 1;
2049
2050 /*
2051 * If we cross a physical cluster boundary within a logical cluster...
2052 */
2053 if (last_pblk && (lblk & cluster_mask) != 0 &&
2054 EXT2FS_B2C(ctx->fs, lblk) == EXT2FS_B2C(ctx->fs, last_lblk) &&
2055 EXT2FS_B2C(ctx->fs, pblk) != EXT2FS_B2C(ctx->fs, last_pblk))
2056 return 1;
2057
2058 return 0;
2059}
2060
15d482ba 2061static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
d5a8f9a9 2062 struct process_block_struct *pb,
d3f32c2d 2063 blk64_t start_block, blk64_t end_block,
085757fc 2064 blk64_t eof_block,
35c8faaf
DW
2065 ext2_extent_handle_t ehandle,
2066 int try_repairs)
15d482ba
TT
2067{
2068 struct ext2fs_extent extent;
d3f32c2d 2069 blk64_t blk, last_lblk;
15d482ba 2070 e2_blkcnt_t blockcnt;
2acad6b4 2071 unsigned int i;
15d482ba 2072 int is_dir, is_leaf;
3c7c6d73 2073 problem_t problem;
11de9261 2074 struct ext2_extent_info info;
49fed79e
DW
2075 int failed_csum = 0;
2076
2077 if (pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID)
2078 failed_csum = 1;
15d482ba 2079
11de9261
TT
2080 pctx->errcode = ext2fs_extent_get_info(ehandle, &info);
2081 if (pctx->errcode)
2082 return;
15d482ba
TT
2083
2084 pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
2085 &extent);
1e2372b3
DW
2086 while ((pctx->errcode == 0 ||
2087 pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID) &&
2088 info.num_entries-- > 0) {
15d482ba
TT
2089 is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
2090 is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
d3f32c2d 2091 last_lblk = extent.e_lblk + extent.e_len - 1;
15d482ba
TT
2092
2093 problem = 0;
ae23dd19
DW
2094 pctx->blk = extent.e_pblk;
2095 pctx->blk2 = extent.e_lblk;
2096 pctx->num = extent.e_len;
2097 pctx->blkcount = extent.e_lblk + extent.e_len;
2098
e6238d37
TT
2099 if (extent.e_pblk == 0 ||
2100 extent.e_pblk < ctx->fs->super->s_first_data_block ||
4efbac6f 2101 extent.e_pblk >= ext2fs_blocks_count(ctx->fs->super))
15d482ba 2102 problem = PR_1_EXTENT_BAD_START_BLK;
d5a8f9a9
TT
2103 else if (extent.e_lblk < start_block)
2104 problem = PR_1_OUT_OF_ORDER_EXTENTS;
085757fc
EW
2105 else if ((end_block && last_lblk > end_block) &&
2106 (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT &&
2107 last_lblk > eof_block)))
d3f32c2d 2108 problem = PR_1_EXTENT_END_OUT_OF_BOUNDS;
9c40d148 2109 else if (is_leaf && extent.e_len == 0)
26c09eb8 2110 problem = PR_1_EXTENT_LENGTH_ZERO;
7a1eac2f
ES
2111 else if (is_leaf &&
2112 (extent.e_pblk + extent.e_len) >
4efbac6f 2113 ext2fs_blocks_count(ctx->fs->super))
15d482ba 2114 problem = PR_1_EXTENT_ENDS_BEYOND;
dd50ef87
TT
2115 else if (is_leaf && is_dir &&
2116 ((extent.e_lblk + extent.e_len) >
2117 (1 << (21 - ctx->fs->super->s_log_block_size))))
2118 problem = PR_1_TOOBIG_DIR;
15d482ba 2119
57b7fabc
DW
2120 /*
2121 * Uninitialized blocks in a directory? Clear the flag and
2122 * we'll interpret the blocks later.
2123 */
e05a0563 2124 if (try_repairs && is_dir && problem == 0 &&
57b7fabc
DW
2125 (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT) &&
2126 fix_problem(ctx, PR_1_UNINIT_DBLOCK, pctx)) {
2127 extent.e_flags &= ~EXT2_EXTENT_FLAGS_UNINIT;
2128 pb->inode_modified = 1;
2129 pctx->errcode = ext2fs_extent_replace(ehandle, 0,
2130 &extent);
2131 if (pctx->errcode)
2132 return;
e05a0563 2133 failed_csum = 0;
57b7fabc
DW
2134 }
2135
35c8faaf 2136 if (try_repairs && problem) {
789bd401 2137report_problem:
15d482ba 2138 if (fix_problem(ctx, problem, pctx)) {
1e2372b3 2139fix_problem_now:
27a129f3
DW
2140 if (ctx->invalid_bitmaps) {
2141 /*
2142 * If fsck knows the bitmaps are bad,
2143 * skip to the next extent and
2144 * try to clear this extent again
2145 * after fixing the bitmaps, by
2146 * restarting fsck.
2147 */
2148 pctx->errcode = ext2fs_extent_get(
2149 ehandle,
2150 EXT2_EXTENT_NEXT_SIB,
2151 &extent);
2152 ctx->flags |= E2F_FLAG_RESTART_LATER;
2153 if (pctx->errcode ==
2154 EXT2_ET_NO_CURRENT_NODE) {
2155 pctx->errcode = 0;
2156 break;
2157 }
2158 continue;
2159 }
19f433a5 2160 e2fsck_read_bitmaps(ctx);
23d6dd1f 2161 pb->inode_modified = 1;
15d482ba
TT
2162 pctx->errcode =
2163 ext2fs_extent_delete(ehandle, 0);
2164 if (pctx->errcode) {
7518c176 2165 pctx->str = "ext2fs_extent_delete";
15d482ba
TT
2166 return;
2167 }
7722961d
TT
2168 pctx->errcode = ext2fs_extent_fix_parents(ehandle);
2169 if (pctx->errcode &&
2170 pctx->errcode != EXT2_ET_NO_CURRENT_NODE) {
2171 pctx->str = "ext2fs_extent_fix_parents";
2172 return;
2173 }
73e5abcf
TT
2174 pctx->errcode = ext2fs_extent_get(ehandle,
2175 EXT2_EXTENT_CURRENT,
2176 &extent);
2177 if (pctx->errcode == EXT2_ET_NO_CURRENT_NODE) {
2178 pctx->errcode = 0;
2179 break;
2180 }
49fed79e 2181 failed_csum = 0;
73e5abcf 2182 continue;
15d482ba
TT
2183 }
2184 goto next;
2185 }
2186
2187 if (!is_leaf) {
d3f32c2d 2188 blk64_t lblk = extent.e_lblk;
35c8faaf 2189 int next_try_repairs = 1;
789bd401 2190
7518c176 2191 blk = extent.e_pblk;
35c8faaf
DW
2192
2193 /*
2194 * If this lower extent block collides with critical
2195 * metadata, don't try to repair the damage. Pass 1b
2196 * will reallocate the block; then we can try again.
2197 */
2198 if (pb->ino != EXT2_RESIZE_INO &&
2199 ext2fs_test_block_bitmap2(ctx->block_metadata_map,
2200 extent.e_pblk)) {
2201 next_try_repairs = 0;
2202 pctx->blk = blk;
2203 fix_problem(ctx,
2204 PR_1_CRITICAL_METADATA_COLLISION,
2205 pctx);
2206 ctx->flags |= E2F_FLAG_RESTART_LATER;
2207 }
15d482ba
TT
2208 pctx->errcode = ext2fs_extent_get(ehandle,
2209 EXT2_EXTENT_DOWN, &extent);
49fed79e
DW
2210 if (pctx->errcode &&
2211 pctx->errcode != EXT2_ET_EXTENT_CSUM_INVALID) {
7518c176
TT
2212 pctx->str = "EXT2_EXTENT_DOWN";
2213 problem = PR_1_EXTENT_HEADER_INVALID;
35c8faaf
DW
2214 if (!next_try_repairs)
2215 return;
49fed79e 2216 if (pctx->errcode == EXT2_ET_EXTENT_HEADER_BAD)
7518c176
TT
2217 goto report_problem;
2218 return;
15d482ba 2219 }
789bd401
ES
2220 /* The next extent should match this index's logical start */
2221 if (extent.e_lblk != lblk) {
68477355 2222 struct ext2_extent_info e_info;
789bd401 2223
68477355 2224 ext2fs_extent_get_info(ehandle, &e_info);
789bd401
ES
2225 pctx->blk = lblk;
2226 pctx->blk2 = extent.e_lblk;
68477355 2227 pctx->num = e_info.curr_level - 1;
789bd401 2228 problem = PR_1_EXTENT_INDEX_START_INVALID;
ec3a42b1 2229 if (fix_problem(ctx, problem, pctx)) {
23d6dd1f 2230 pb->inode_modified = 1;
ec3a42b1
DW
2231 pctx->errcode =
2232 ext2fs_extent_fix_parents(ehandle);
7722961d
TT
2233 if (pctx->errcode) {
2234 pctx->str = "ext2fs_extent_fix_parents";
ec3a42b1 2235 return;
7722961d 2236 }
ec3a42b1 2237 }
789bd401 2238 }
d3f32c2d 2239 scan_extent_node(ctx, pctx, pb, extent.e_lblk,
35c8faaf
DW
2240 last_lblk, eof_block, ehandle,
2241 next_try_repairs);
7518c176
TT
2242 if (pctx->errcode)
2243 return;
15d482ba
TT
2244 pctx->errcode = ext2fs_extent_get(ehandle,
2245 EXT2_EXTENT_UP, &extent);
2246 if (pctx->errcode) {
7518c176
TT
2247 pctx->str = "EXT2_EXTENT_UP";
2248 return;
15d482ba 2249 }
7518c176
TT
2250 mark_block_used(ctx, blk);
2251 pb->num_blocks++;
15d482ba
TT
2252 goto next;
2253 }
2254
63b5e354
TT
2255 if ((pb->previous_block != 0) &&
2256 (pb->previous_block+1 != extent.e_pblk)) {
100d4701
TT
2257 if (ctx->options & E2F_OPT_FRAGCHECK) {
2258 char type = '?';
2259
2260 if (pb->is_dir)
2261 type = 'd';
2262 else if (pb->is_reg)
2263 type = 'f';
2264
2265 printf(("%6lu(%c): expecting %6lu "
2266 "actual extent "
63b5e354 2267 "phys %6lu log %lu len %lu\n"),
100d4701 2268 (unsigned long) pctx->ino, type,
63b5e354
TT
2269 (unsigned long) pb->previous_block+1,
2270 (unsigned long) extent.e_pblk,
2271 (unsigned long) extent.e_lblk,
2272 (unsigned long) extent.e_len);
100d4701 2273 }
63b5e354
TT
2274 pb->fragmented = 1;
2275 }
9f005a90
DW
2276 /*
2277 * If we notice a gap in the logical block mappings of an
2278 * extent-mapped directory, offer to close the hole by
2279 * moving the logical block down, otherwise we'll go mad in
2280 * pass 3 allocating empty directory blocks to fill the hole.
2281 */
60203cb1 2282 if (try_repairs && is_dir &&
9f005a90
DW
2283 pb->last_block + 1 < (e2_blkcnt_t)extent.e_lblk) {
2284 blk64_t new_lblk;
2285
2286 new_lblk = pb->last_block + 1;
2287 if (EXT2FS_CLUSTER_RATIO(ctx->fs) > 1)
2288 new_lblk = ((new_lblk +
2289 EXT2FS_CLUSTER_RATIO(ctx->fs)) &
2290 EXT2FS_CLUSTER_MASK(ctx->fs)) |
2291 (extent.e_lblk &
2292 EXT2FS_CLUSTER_MASK(ctx->fs));
2293 pctx->blk = extent.e_lblk;
2294 pctx->blk2 = new_lblk;
2295 if (fix_problem(ctx, PR_1_COLLAPSE_DBLOCK, pctx)) {
2296 extent.e_lblk = new_lblk;
2297 pb->inode_modified = 1;
2298 pctx->errcode = ext2fs_extent_replace(ehandle,
2299 0, &extent);
2300 if (pctx->errcode) {
2301 pctx->errcode = 0;
2302 goto alloc_later;
2303 }
2304 pctx->errcode = ext2fs_extent_fix_parents(ehandle);
2305 if (pctx->errcode)
2306 goto failed_add_dir_block;
2307 pctx->errcode = ext2fs_extent_goto(ehandle,
2308 extent.e_lblk);
2309 if (pctx->errcode)
2310 goto failed_add_dir_block;
2311 last_lblk = extent.e_lblk + extent.e_len - 1;
49fed79e 2312 failed_csum = 0;
9f005a90
DW
2313 }
2314 }
2315alloc_later:
68477355
TT
2316 while (is_dir && (++pb->last_db_block <
2317 (e2_blkcnt_t) extent.e_lblk)) {
6dc64392
VAH
2318 pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
2319 pb->ino, 0,
2320 pb->last_db_block);
4607ef7d
TT
2321 if (pctx->errcode) {
2322 pctx->blk = 0;
2323 pctx->num = pb->last_db_block;
2324 goto failed_add_dir_block;
2325 }
2326 }
2ae49fd0
TT
2327 if (!ctx->fs->cluster_ratio_bits) {
2328 mark_blocks_used(ctx, extent.e_pblk, extent.e_len);
2329 pb->num_blocks += extent.e_len;
2330 }
15d482ba
TT
2331 for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
2332 i < extent.e_len;
2333 blk++, blockcnt++, i++) {
2ae49fd0
TT
2334 if (ctx->fs->cluster_ratio_bits &&
2335 !(pb->previous_block &&
44fe08f1
TT
2336 (EXT2FS_B2C(ctx->fs, blk) ==
2337 EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
2338 (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
68477355 2339 ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
44fe08f1 2340 mark_block_used(ctx, blk);
b2e6c86d
TT
2341 pb->num_blocks++;
2342 }
9a1d614d
DW
2343 if (has_unaligned_cluster_map(ctx, pb->previous_block,
2344 pb->last_block, blk,
2345 blockcnt)) {
2346 pctx->blk = blockcnt;
2347 pctx->blk2 = blk;
2348 fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
2349 mark_block_used(ctx, blk);
2350 mark_block_used(ctx, blk);
2351 }
2352 pb->last_block = blockcnt;
44fe08f1 2353 pb->previous_block = blk;
15d482ba
TT
2354
2355 if (is_dir) {
6dc64392 2356 pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
15d482ba
TT
2357 if (pctx->errcode) {
2358 pctx->blk = blk;
2359 pctx->num = blockcnt;
4607ef7d 2360 failed_add_dir_block:
15d482ba
TT
2361 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
2362 /* Should never get here */
2363 ctx->flags |= E2F_FLAG_ABORT;
2364 return;
2365 }
2366 }
2367 }
4607ef7d
TT
2368 if (is_dir && extent.e_len > 0)
2369 pb->last_db_block = blockcnt - 1;
63b5e354 2370 pb->previous_block = extent.e_pblk + extent.e_len - 1;
d3f32c2d 2371 start_block = pb->last_block = last_lblk;
010dc7b9
LC
2372 if (is_leaf && !is_dir &&
2373 !(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT))
d3f32c2d 2374 pb->last_init_lblock = last_lblk;
15d482ba
TT
2375 next:
2376 pctx->errcode = ext2fs_extent_get(ehandle,
2377 EXT2_EXTENT_NEXT_SIB,
2378 &extent);
2379 }
49fed79e
DW
2380
2381 /* Failed csum but passes checks? Ask to fix checksum. */
2382 if (failed_csum &&
2383 fix_problem(ctx, PR_1_EXTENT_ONLY_CSUM_INVALID, pctx)) {
2384 pb->inode_modified = 1;
2385 pctx->errcode = ext2fs_extent_replace(ehandle, 0, &extent);
2386 if (pctx->errcode)
2387 return;
2388 }
2389
15d482ba
TT
2390 if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
2391 pctx->errcode = 0;
2392}
2393
2394static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
2acad6b4 2395 struct process_block_struct *pb)
15d482ba 2396{
8da6d1a1 2397 struct ext2_extent_info info;
15d482ba
TT
2398 struct ext2_inode *inode = pctx->inode;
2399 ext2_extent_handle_t ehandle;
2400 ext2_filsys fs = ctx->fs;
2401 ext2_ino_t ino = pctx->ino;
8da6d1a1 2402 errcode_t retval;
085757fc 2403 blk64_t eof_lblk;
15d482ba 2404
84b239ae 2405 pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
0a68b181
TT
2406 if (pctx->errcode) {
2407 if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
2408 e2fsck_clear_inode(ctx, ino, inode, 0,
2409 "check_blocks_extents");
15d482ba
TT
2410 pctx->errcode = 0;
2411 return;
2412 }
2413
8da6d1a1
TT
2414 retval = ext2fs_extent_get_info(ehandle, &info);
2415 if (retval == 0) {
2416 if (info.max_depth >= MAX_EXTENT_DEPTH_COUNT)
2417 info.max_depth = MAX_EXTENT_DEPTH_COUNT-1;
2418 ctx->extent_depth_count[info.max_depth]++;
2419 }
2420
085757fc
EW
2421 eof_lblk = ((EXT2_I_SIZE(inode) + fs->blocksize - 1) >>
2422 EXT2_BLOCK_SIZE_BITS(fs->super)) - 1;
35c8faaf 2423 scan_extent_node(ctx, pctx, pb, 0, 0, eof_lblk, ehandle, 1);
7518c176
TT
2424 if (pctx->errcode &&
2425 fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
2426 pb->num_blocks = 0;
2427 inode->i_blocks = 0;
2428 e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
2429 "check_blocks_extents");
2430 pctx->errcode = 0;
2431 }
15d482ba
TT
2432 ext2fs_extent_free(ehandle);
2433}
2434
042e0719
ZL
2435/*
2436 * In fact we don't need to check blocks for an inode with inline data
2437 * because this inode doesn't have any blocks. In this function all
2438 * we need to do is add this inode into dblist when it is a directory.
2439 */
2440static void check_blocks_inline_data(e2fsck_t ctx, struct problem_context *pctx,
2441 struct process_block_struct *pb)
2442{
cc7d12ac
DW
2443 if (!pb->is_dir) {
2444 pctx->errcode = 0;
042e0719 2445 return;
cc7d12ac 2446 }
042e0719
ZL
2447
2448 pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pb->ino, 0, 0);
2449 if (pctx->errcode) {
2450 pctx->blk = 0;
2451 pctx->num = 0;
2452 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
2453 ctx->flags |= E2F_FLAG_ABORT;
2454 }
2455}
2456
3839e657
TT
2457/*
2458 * This subroutine is called on each inode to account for all of the
2459 * blocks used by that inode.
2460 */
1b6bf175 2461static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657
TT
2462 char *block_buf)
2463{
1b6bf175 2464 ext2_filsys fs = ctx->fs;
3839e657 2465 struct process_block_struct pb;
86c627ec 2466 ext2_ino_t ino = pctx->ino;
21c84b71 2467 struct ext2_inode *inode = pctx->inode;
3971bfe8 2468 unsigned bad_size = 0;
503f9e7f 2469 int dirty_inode = 0;
7c1e090c 2470 int extent_fs;
042e0719 2471 int inlinedata_fs;
246501c6 2472 __u64 size;
efc6f628 2473
3839e657 2474 pb.ino = ino;
0684a4f3
TT
2475 pb.num_blocks = 0;
2476 pb.last_block = -1;
010dc7b9 2477 pb.last_init_lblock = -1;
4dbe79bc 2478 pb.last_db_block = -1;
f3db3566 2479 pb.num_illegal_blocks = 0;
21c84b71 2480 pb.suppress = 0; pb.clear = 0;
74becf3c 2481 pb.fragmented = 0;
1917875f 2482 pb.compressed = 0;
74becf3c 2483 pb.previous_block = 0;
b94a052a 2484 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
da307041
TT
2485 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
2486 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
f3db3566 2487 pb.inode = inode;
21c84b71 2488 pb.pctx = pctx;
1b6bf175 2489 pb.ctx = ctx;
23d6dd1f 2490 pb.inode_modified = 0;
35c8faaf 2491 pb.bad_ref = 0;
1b6bf175 2492 pctx->ino = ino;
0684a4f3 2493 pctx->errcode = 0;
1917875f 2494
7c1e090c
ES
2495 extent_fs = (ctx->fs->super->s_feature_incompat &
2496 EXT3_FEATURE_INCOMPAT_EXTENTS);
042e0719
ZL
2497 inlinedata_fs = (ctx->fs->super->s_feature_incompat &
2498 EXT4_FEATURE_INCOMPAT_INLINE_DATA);
7c1e090c 2499
1917875f 2500 if (inode->i_flags & EXT2_COMPRBLK_FL) {
f5ae75e5
TT
2501 if (fs->super->s_feature_incompat &
2502 EXT2_FEATURE_INCOMPAT_COMPRESSION)
1917875f
TT
2503 pb.compressed = 1;
2504 else {
2505 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
2506 inode->i_flags &= ~EXT2_COMPRBLK_FL;
503f9e7f 2507 dirty_inode++;
1917875f
TT
2508 }
2509 }
2510 }
2511
5b9cbd76 2512 if (check_ext_attr(ctx, pctx, block_buf)) {
fefaef39
AD
2513 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2514 goto out;
dc71f23e 2515 pb.num_blocks++;
fefaef39 2516 }
dc71f23e 2517
0c80c44b 2518 if (ext2fs_inode_has_valid_blocks2(fs, inode)) {
7c1e090c 2519 if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
2acad6b4 2520 check_blocks_extents(ctx, pctx, &pb);
010dc7b9 2521 else {
d4864e02 2522 int flags;
23d6dd1f
DW
2523 /*
2524 * If we've modified the inode, write it out before
2525 * iterate() tries to use it.
2526 */
2527 if (dirty_inode) {
2528 e2fsck_write_inode(ctx, ino, inode,
2529 "check_blocks");
2530 dirty_inode = 0;
2531 }
d4864e02 2532 flags = fs->flags;
f9f3050a 2533 fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
6dc64392 2534 pctx->errcode = ext2fs_block_iterate3(fs, ino,
15d482ba
TT
2535 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
2536 block_buf, process_block, &pb);
010dc7b9
LC
2537 /*
2538 * We do not have uninitialized extents in non extent
2539 * files.
2540 */
2541 pb.last_init_lblock = pb.last_block;
23d6dd1f
DW
2542 /*
2543 * If iterate() changed a block mapping, we have to
2544 * re-read the inode. If we decide to clear the
2545 * inode after clearing some stuff, we'll re-write the
2546 * bad mappings into the inode!
2547 */
2548 if (pb.inode_modified)
2549 e2fsck_read_inode(ctx, ino, inode,
2550 "check_blocks");
d4864e02
DW
2551 fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
2552 (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
010dc7b9 2553 }
042e0719
ZL
2554 } else {
2555 /* check inline data */
2556 if (inlinedata_fs && (inode->i_flags & EXT4_INLINE_DATA_FL))
2557 check_blocks_inline_data(ctx, pctx, &pb);
15d482ba 2558 }
1b6bf175 2559 end_problem_latch(ctx, PR_LATCH_BLOCK);
da307041 2560 end_problem_latch(ctx, PR_LATCH_TOOBIG);
0684a4f3
TT
2561 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2562 goto out;
1b6bf175
TT
2563 if (pctx->errcode)
2564 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
3839e657 2565
ce44d8ca
TT
2566 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group) {
2567 if (LINUX_S_ISDIR(inode->i_mode))
2568 ctx->fs_fragmented_dir++;
2569 else
2570 ctx->fs_fragmented++;
2571 }
74becf3c 2572
f3db3566 2573 if (pb.clear) {
e3df15ab
TT
2574 e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
2575 "check_blocks");
2576 return;
f3db3566 2577 }
efc6f628 2578
8fdc9985 2579 if (inode->i_flags & EXT2_INDEX_FL) {
503f9e7f
TT
2580 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
2581 inode->i_flags &= ~EXT2_INDEX_FL;
2582 dirty_inode++;
2583 } else {
8fdc9985
TT
2584#ifdef ENABLE_HTREE
2585 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
2586#endif
503f9e7f 2587 }
8fdc9985 2588 }
efc6f628 2589
042e0719
ZL
2590 if (!pb.num_blocks && pb.is_dir &&
2591 !(inode->i_flags & EXT4_INLINE_DATA_FL)) {
1b6bf175 2592 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
e3df15ab 2593 e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
1b6bf175 2594 ctx->fs_directory_count--;
e3df15ab 2595 return;
21c84b71 2596 }
3839e657 2597 }
0684a4f3 2598
624e4a64
AK
2599 if (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) {
2600 quota_data_add(ctx->qctx, inode, ino,
2601 pb.num_blocks * fs->blocksize);
2602 quota_data_inodes(ctx->qctx, inode, ino, +1);
2603 }
2604
1ca1059f
TT
2605 if (!(fs->super->s_feature_ro_compat &
2606 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
2607 !(inode->i_flags & EXT4_HUGE_FILE_FL))
2608 pb.num_blocks *= (fs->blocksize / 512);
b2e6c86d 2609 pb.num_blocks *= EXT2FS_CLUSTER_RATIO(fs);
0684a4f3 2610#if 0
b2e6c86d 2611 printf("inode %u, i_size = %u, last_block = %lld, i_blocks=%llu, num_blocks = %llu\n",
6dc64392 2612 ino, inode->i_size, pb.last_block, ext2fs_inode_i_blocks(fs, inode),
0684a4f3
TT
2613 pb.num_blocks);
2614#endif
246501c6
TT
2615 if (pb.is_dir) {
2616 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
042e0719 2617 if (inode->i_flags & EXT4_INLINE_DATA_FL) {
d4864e02 2618 int flags;
042e0719
ZL
2619 size_t size;
2620
d4864e02
DW
2621 flags = ctx->fs->flags;
2622 ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
042e0719
ZL
2623 if (ext2fs_inline_data_size(ctx->fs, pctx->ino, &size))
2624 bad_size = 5;
d4864e02
DW
2625 ctx->fs->flags = (flags &
2626 EXT2_FLAG_IGNORE_CSUM_ERRORS) |
2627 (ctx->fs->flags &
2628 ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
042e0719
ZL
2629 if (size != inode->i_size)
2630 bad_size = 5;
2631 } else if (inode->i_size & (fs->blocksize - 1))
2cd12338
TT
2632 bad_size = 5;
2633 else if (nblock > (pb.last_block + 1))
246501c6
TT
2634 bad_size = 1;
2635 else if (nblock < (pb.last_block + 1)) {
246501c6 2636 if (((pb.last_block + 1) - nblock) >
5dd8f963 2637 fs->super->s_prealloc_dir_blocks)
9d1bd3de 2638 bad_size = 2;
246501c6
TT
2639 }
2640 } else {
9f0288d3
TT
2641 e2_blkcnt_t blkpg = ctx->blocks_per_page;
2642
4f489285 2643 size = EXT2_I_SIZE(inode);
010dc7b9 2644 if ((pb.last_init_lblock >= 0) &&
9f0288d3 2645 /* allow allocated blocks to end of PAGE_SIZE */
010dc7b9
LC
2646 (size < (__u64)pb.last_init_lblock * fs->blocksize) &&
2647 (pb.last_init_lblock / blkpg * blkpg != pb.last_init_lblock ||
2648 size < (__u64)(pb.last_init_lblock & ~(blkpg-1)) *
2649 fs->blocksize))
9d1bd3de 2650 bad_size = 3;
7c1e090c
ES
2651 else if (!(extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
2652 size > ext2_max_sizes[fs->super->s_log_block_size])
2653 /* too big for a direct/indirect-mapped file */
9d1bd3de 2654 bad_size = 4;
7c1e090c 2655 else if ((extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
3ec7be43 2656 size >
03fa6f8a 2657 ((1ULL << (32 + EXT2_BLOCK_SIZE_BITS(fs->super))) - 1))
7c1e090c
ES
2658 /* too big for an extent-based file - 32bit ee_block */
2659 bad_size = 6;
246501c6 2660 }
0684a4f3
TT
2661 /* i_size for symlinks is checked elsewhere */
2662 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
21c84b71 2663 pctx->num = (pb.last_block+1) * fs->blocksize;
3ec7be43 2664 pctx->group = bad_size;
1b6bf175 2665 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
97c607b1
DW
2666 if (LINUX_S_ISDIR(inode->i_mode))
2667 pctx->num &= 0xFFFFFFFFULL;
2668 ext2fs_inode_size_set(fs, inode, pctx->num);
503f9e7f 2669 dirty_inode++;
21c84b71
TT
2670 }
2671 pctx->num = 0;
3839e657 2672 }
3b6c0938
DW
2673 if (LINUX_S_ISREG(inode->i_mode) &&
2674 ext2fs_needs_large_file_feature(EXT2_I_SIZE(inode)))
246501c6 2675 ctx->large_files++;
8a8f3654 2676 if ((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) ||
1ca1059f
TT
2677 ((fs->super->s_feature_ro_compat &
2678 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
2679 (inode->i_flags & EXT4_HUGE_FILE_FL) &&
2680 (inode->osd2.linux2.l_i_blocks_hi != 0))) {
21c84b71 2681 pctx->num = pb.num_blocks;
1b6bf175 2682 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
3839e657 2683 inode->i_blocks = pb.num_blocks;
b70506bf 2684 inode->osd2.linux2.l_i_blocks_hi = pb.num_blocks >> 32;
503f9e7f 2685 dirty_inode++;
21c84b71
TT
2686 }
2687 pctx->num = 0;
3839e657 2688 }
a49249d2
TT
2689
2690 if (ctx->dirs_to_hash && pb.is_dir &&
82372e32 2691 !(ctx->lost_and_found && ctx->lost_and_found == ino) &&
a49249d2
TT
2692 !(inode->i_flags & EXT2_INDEX_FL) &&
2693 ((inode->i_size / fs->blocksize) >= 3))
07307114 2694 e2fsck_rehash_dir_later(ctx, ino);
a49249d2 2695
503f9e7f
TT
2696out:
2697 if (dirty_inode)
2698 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
50e1e10f
TT
2699}
2700
21c84b71 2701#if 0
50e1e10f
TT
2702/*
2703 * Helper function called by process block when an illegal block is
2704 * found. It returns a description about why the block is illegal
2705 */
6dc64392 2706static char *describe_illegal_block(ext2_filsys fs, blk64_t block)
50e1e10f 2707{
6dc64392 2708 blk64_t super;
50e1e10f
TT
2709 int i;
2710 static char problem[80];
2711
2712 super = fs->super->s_first_data_block;
2713 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
2714 if (block < super) {
2715 sprintf(problem, "< FIRSTBLOCK (%u)", super);
2716 return(problem);
4efbac6f
VAH
2717 } else if (block >= ext2fs_blocks_count(fs->super)) {
2718 sprintf(problem, "> BLOCKS (%u)", ext2fs_blocks_count(fs->super));
50e1e10f
TT
2719 return(problem);
2720 }
2721 for (i = 0; i < fs->group_desc_count; i++) {
2722 if (block == super) {
2723 sprintf(problem, "is the superblock in group %d", i);
2724 break;
2725 }
2726 if (block > super &&
2727 block <= (super + fs->desc_blocks)) {
2728 sprintf(problem, "is in the group descriptors "
2729 "of group %d", i);
2730 break;
2731 }
d7cca6b0 2732 if (block == ext2fs_block_bitmap_loc(fs, i)) {
50e1e10f
TT
2733 sprintf(problem, "is the block bitmap of group %d", i);
2734 break;
2735 }
d7cca6b0 2736 if (block == ext2fs_inode_bitmap_loc(fs, i)) {
50e1e10f
TT
2737 sprintf(problem, "is the inode bitmap of group %d", i);
2738 break;
2739 }
d7cca6b0
VAH
2740 if (block >= ext2fs_inode_table_loc(fs, i) &&
2741 (block < ext2fs_inode_table_loc(fs, i)
50e1e10f
TT
2742 + fs->inode_blocks_per_group)) {
2743 sprintf(problem, "is in the inode table of group %d",
2744 i);
2745 break;
2746 }
2747 super += fs->super->s_blocks_per_group;
2748 }
2749 return(problem);
2750}
21c84b71 2751#endif
3839e657
TT
2752
2753/*
2754 * This is a helper function for check_blocks().
2755 */
53ef44c4 2756static int process_block(ext2_filsys fs,
6dc64392 2757 blk64_t *block_nr,
9d1bd3de 2758 e2_blkcnt_t blockcnt,
6dc64392 2759 blk64_t ref_block EXT2FS_ATTR((unused)),
54434927 2760 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 2761 void *priv_data)
3839e657
TT
2762{
2763 struct process_block_struct *p;
21c84b71 2764 struct problem_context *pctx;
6dc64392 2765 blk64_t blk = *block_nr;
50e1e10f 2766 int ret_code = 0;
3c7c6d73 2767 problem_t problem = 0;
1b6bf175 2768 e2fsck_t ctx;
3839e657 2769
54dc7ca2 2770 p = (struct process_block_struct *) priv_data;
21c84b71 2771 pctx = p->pctx;
1b6bf175 2772 ctx = p->ctx;
3839e657 2773
1917875f
TT
2774 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
2775 /* todo: Check that the comprblk_fl is high, that the
2776 blkaddr pattern looks right (all non-holes up to
2777 first EXT2FS_COMPRESSED_BLKADDR, then all
2778 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
2779 that the feature_incompat bit is high, and that the
2780 inode is a regular file. If we're doing a "full
2781 check" (a concept introduced to e2fsck by e2compr,
2782 meaning that we look at data blocks as well as
2783 metadata) then call some library routine that
2784 checks the compressed data. I'll have to think
2785 about this, because one particularly important
2786 problem to be able to fix is to recalculate the
2787 cluster size if necessary. I think that perhaps
2788 we'd better do most/all e2compr-specific checks
2789 separately, after the non-e2compr checks. If not
2790 doing a full check, it may be useful to test that
2791 the personality is linux; e.g. if it isn't then
2792 perhaps this really is just an illegal block. */
2793 return 0;
2794 }
b94a052a 2795
0733835b
DW
2796 /*
2797 * For a directory, add logical block zero for processing even if it's
2798 * not mapped or we'll be perennially stuck with broken "." and ".."
2799 * entries.
2800 */
2801 if (p->is_dir && blockcnt == 0 && blk == 0) {
2802 pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino, 0, 0);
2803 if (pctx->errcode) {
2804 pctx->blk = blk;
2805 pctx->num = blockcnt;
2806 goto failed_add_dir_block;
2807 }
2808 p->last_db_block++;
2809 }
2810
4dbe79bc 2811 if (blk == 0)
50e1e10f 2812 return 0;
50e1e10f 2813
3839e657 2814#if 0
50e1e10f 2815 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
3839e657 2816 blockcnt);
50e1e10f 2817#endif
efc6f628 2818
74becf3c
TT
2819 /*
2820 * Simplistic fragmentation check. We merely require that the
2821 * file be contiguous. (Which can never be true for really
2822 * big files that are greater than a block group.)
2823 */
63b5e354
TT
2824 if (!HOLE_BLKADDR(p->previous_block) && p->ino != EXT2_RESIZE_INO) {
2825 if (p->previous_block+1 != blk) {
100d4701
TT
2826 if (ctx->options & E2F_OPT_FRAGCHECK) {
2827 char type = '?';
2828
2829 if (p->is_dir)
2830 type = 'd';
2831 else if (p->is_reg)
2832 type = 'f';
2833
2834 printf(_("%6lu(%c): expecting %6lu "
2835 "got phys %6lu (blkcnt %lld)\n"),
2836 (unsigned long) pctx->ino, type,
63b5e354
TT
2837 (unsigned long) p->previous_block+1,
2838 (unsigned long) blk,
f4e2c991 2839 blockcnt);
100d4701 2840 }
74becf3c 2841 p->fragmented = 1;
63b5e354 2842 }
74becf3c 2843 }
503f9e7f 2844
8421fb67 2845 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
da307041
TT
2846 problem = PR_1_TOOBIG_DIR;
2847 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
2848 problem = PR_1_TOOBIG_REG;
2849 if (!p->is_dir && !p->is_reg && blockcnt > 0)
2850 problem = PR_1_TOOBIG_SYMLINK;
efc6f628 2851
50e1e10f 2852 if (blk < fs->super->s_first_data_block ||
4efbac6f 2853 blk >= ext2fs_blocks_count(fs->super))
21c84b71 2854 problem = PR_1_ILLEGAL_BLOCK_NUM;
21c84b71 2855
35c8faaf
DW
2856 /*
2857 * If this IND/DIND/TIND block is squatting atop some critical metadata
2858 * (group descriptors, superblock, bitmap, inode table), any write to
2859 * "fix" mapping problems will destroy the metadata. We'll let pass 1b
2860 * fix that and restart fsck.
2861 */
2862 if (blockcnt < 0 &&
2863 p->ino != EXT2_RESIZE_INO &&
2864 ext2fs_test_block_bitmap2(ctx->block_metadata_map, blk)) {
2865 p->bad_ref = blk;
2866 pctx->blk = blk;
2867 fix_problem(ctx, PR_1_CRITICAL_METADATA_COLLISION, pctx);
2868 ctx->flags |= E2F_FLAG_RESTART_LATER;
2869 }
2870
21c84b71 2871 if (problem) {
f3db3566 2872 p->num_illegal_blocks++;
35c8faaf
DW
2873 /*
2874 * A bit of subterfuge here -- we're trying to fix a block
2875 * mapping, but know that the IND/DIND/TIND block has collided
2876 * with some critical metadata. So, fix the in-core mapping so
2877 * iterate won't go insane, but return 0 instead of
2878 * BLOCK_CHANGED so that it won't write the remapping out to
2879 * our multiply linked block.
2880 */
2881 if (p->bad_ref && ref_block == p->bad_ref) {
2882 *block_nr = 0;
2883 return 0;
2884 }
21c84b71 2885 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
1b6bf175 2886 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
f3db3566
TT
2887 p->clear = 1;
2888 return BLOCK_ABORT;
2889 }
f8188fff 2890 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
f3db3566 2891 p->suppress = 1;
1b6bf175
TT
2892 set_latch_flags(PR_LATCH_BLOCK,
2893 PRL_SUPPRESS, 0);
f3db3566
TT
2894 }
2895 }
21c84b71
TT
2896 pctx->blk = blk;
2897 pctx->blkcount = blockcnt;
1b6bf175 2898 if (fix_problem(ctx, problem, pctx)) {
50e1e10f
TT
2899 blk = *block_nr = 0;
2900 ret_code = BLOCK_CHANGED;
23d6dd1f 2901 p->inode_modified = 1;
c28c2741
DW
2902 /*
2903 * If the directory block is too big and is beyond the
2904 * end of the FS, don't bother trying to add it for
2905 * processing -- the kernel would never have created a
2906 * directory this large, and we risk an ENOMEM abort.
2907 * In any case, the toobig handler for extent-based
2908 * directories also doesn't feed toobig blocks to
2909 * pass 2.
2910 */
2911 if (problem == PR_1_TOOBIG_DIR)
2912 return ret_code;
50e1e10f 2913 goto mark_dir;
21c84b71 2914 } else
3839e657 2915 return 0;
3839e657
TT
2916 }
2917
d323f8fb 2918 if (p->ino == EXT2_RESIZE_INO) {
efc6f628 2919 /*
c3ffaf83
TT
2920 * The resize inode has already be sanity checked
2921 * during pass #0 (the superblock checks). All we
2922 * have to do is mark the double indirect block as
2923 * being in use; all of the other blocks are handled
2924 * by mark_table_blocks()).
2925 */
2926 if (blockcnt == BLOCK_COUNT_DIND)
d323f8fb 2927 mark_block_used(ctx, blk);
95a7f15f
TT
2928 p->num_blocks++;
2929 } else if (!(ctx->fs->cluster_ratio_bits &&
2930 p->previous_block &&
2931 (EXT2FS_B2C(ctx->fs, blk) ==
2932 EXT2FS_B2C(ctx->fs, p->previous_block)) &&
2933 (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
68477355 2934 ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
d323f8fb 2935 mark_block_used(ctx, blk);
95a7f15f 2936 p->num_blocks++;
9a1d614d
DW
2937 } else if (has_unaligned_cluster_map(ctx, p->previous_block,
2938 p->last_block, blk, blockcnt)) {
2939 pctx->blk = blockcnt;
2940 pctx->blk2 = blk;
2941 fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
2942 mark_block_used(ctx, blk);
2943 mark_block_used(ctx, blk);
95a7f15f 2944 }
1e3472c5
TT
2945 if (blockcnt >= 0)
2946 p->last_block = blockcnt;
95a7f15f 2947 p->previous_block = blk;
50e1e10f 2948mark_dir:
1e3472c5 2949 if (p->is_dir && (blockcnt >= 0)) {
4dbe79bc 2950 while (++p->last_db_block < blockcnt) {
6dc64392
VAH
2951 pctx->errcode = ext2fs_add_dir_block2(fs->dblist,
2952 p->ino, 0,
2953 p->last_db_block);
4dbe79bc
TT
2954 if (pctx->errcode) {
2955 pctx->blk = 0;
2956 pctx->num = p->last_db_block;
2957 goto failed_add_dir_block;
2958 }
2959 }
6dc64392
VAH
2960 pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino,
2961 blk, blockcnt);
1b6bf175
TT
2962 if (pctx->errcode) {
2963 pctx->blk = blk;
2964 pctx->num = blockcnt;
4dbe79bc 2965 failed_add_dir_block:
1b6bf175 2966 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
08b21301
TT
2967 /* Should never get here */
2968 ctx->flags |= E2F_FLAG_ABORT;
2969 return BLOCK_ABORT;
3839e657 2970 }
3839e657 2971 }
50e1e10f 2972 return ret_code;
3839e657
TT
2973}
2974
53ef44c4 2975static int process_bad_block(ext2_filsys fs,
6dc64392 2976 blk64_t *block_nr,
9d1bd3de 2977 e2_blkcnt_t blockcnt,
6dc64392 2978 blk64_t ref_block EXT2FS_ATTR((unused)),
54434927 2979 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 2980 void *priv_data)
3839e657
TT
2981{
2982 struct process_block_struct *p;
6dc64392
VAH
2983 blk64_t blk = *block_nr;
2984 blk64_t first_block;
54434927 2985 dgrp_t i;
21c84b71 2986 struct problem_context *pctx;
1b6bf175 2987 e2fsck_t ctx;
21c84b71 2988
1917875f
TT
2989 /*
2990 * Note: This function processes blocks for the bad blocks
2991 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
2992 */
2993
3839e657
TT
2994 if (!blk)
2995 return 0;
efc6f628 2996
54dc7ca2 2997 p = (struct process_block_struct *) priv_data;
1b6bf175 2998 ctx = p->ctx;
21c84b71 2999 pctx = p->pctx;
efc6f628 3000
f8188fff 3001 pctx->ino = EXT2_BAD_INO;
21c84b71
TT
3002 pctx->blk = blk;
3003 pctx->blkcount = blockcnt;
3839e657
TT
3004
3005 if ((blk < fs->super->s_first_data_block) ||
4efbac6f 3006 (blk >= ext2fs_blocks_count(fs->super))) {
1b6bf175 3007 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
3839e657
TT
3008 *block_nr = 0;
3009 return BLOCK_CHANGED;
21c84b71 3010 } else
3839e657 3011 return 0;
3839e657
TT
3012 }
3013
3014 if (blockcnt < 0) {
c5d2f50d 3015 if (ext2fs_test_block_bitmap2(p->fs_meta_blocks, blk)) {
000ba404
TT
3016 p->bbcheck = 1;
3017 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
3018 *block_nr = 0;
3019 return BLOCK_CHANGED;
3020 }
c5d2f50d 3021 } else if (ext2fs_test_block_bitmap2(ctx->block_found_map,
000ba404
TT
3022 blk)) {
3023 p->bbcheck = 1;
efc6f628 3024 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
000ba404
TT
3025 pctx)) {
3026 *block_nr = 0;
3027 return BLOCK_CHANGED;
3028 }
a02ce9df 3029 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
3030 return BLOCK_ABORT;
3031 } else
1b6bf175 3032 mark_block_used(ctx, blk);
3839e657
TT
3033 return 0;
3034 }
efc6f628 3035#if 0
50e1e10f 3036 printf ("DEBUG: Marking %u as bad.\n", blk);
3839e657 3037#endif
1b6bf175 3038 ctx->fs_badblocks_count++;
3839e657
TT
3039 /*
3040 * If the block is not used, then mark it as used and return.
3041 * If it is already marked as found, this must mean that
3042 * there's an overlap between the filesystem table blocks
3043 * (bitmaps and inode table) and the bad block list.
3044 */
c5d2f50d
VAH
3045 if (!ext2fs_test_block_bitmap2(ctx->block_found_map, blk)) {
3046 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
3839e657
TT
3047 return 0;
3048 }
f3db3566
TT
3049 /*
3050 * Try to find the where the filesystem block was used...
3051 */
3052 first_block = fs->super->s_first_data_block;
efc6f628 3053
f3db3566 3054 for (i = 0; i < fs->group_desc_count; i++ ) {
21c84b71 3055 pctx->group = i;
1b6bf175 3056 pctx->blk = blk;
8039c480
TT
3057 if (!ext2fs_bg_has_super(fs, i))
3058 goto skip_super;
f3db3566
TT
3059 if (blk == first_block) {
3060 if (i == 0) {
1b6bf175
TT
3061 if (fix_problem(ctx,
3062 PR_1_BAD_PRIMARY_SUPERBLOCK,
3063 pctx)) {
3064 *block_nr = 0;
50e1e10f 3065 return BLOCK_CHANGED;
1b6bf175 3066 }
50e1e10f 3067 return 0;
f3db3566 3068 }
1b6bf175 3069 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
f3db3566
TT
3070 return 0;
3071 }
3072 if ((blk > first_block) &&
3073 (blk <= first_block + fs->desc_blocks)) {
3074 if (i == 0) {
1b6bf175
TT
3075 pctx->blk = *block_nr;
3076 if (fix_problem(ctx,
3077 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
3078 *block_nr = 0;
50e1e10f 3079 return BLOCK_CHANGED;
1b6bf175 3080 }
50e1e10f 3081 return 0;
f3db3566 3082 }
1b6bf175 3083 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
f3db3566 3084 return 0;
3839e657 3085 }
8039c480 3086 skip_super:
d7cca6b0 3087 if (blk == ext2fs_block_bitmap_loc(fs, i)) {
1b6bf175
TT
3088 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
3089 ctx->invalid_block_bitmap_flag[i]++;
3090 ctx->invalid_bitmaps++;
21c84b71 3091 }
f3db3566
TT
3092 return 0;
3093 }
d7cca6b0 3094 if (blk == ext2fs_inode_bitmap_loc(fs, i)) {
1b6bf175
TT
3095 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
3096 ctx->invalid_inode_bitmap_flag[i]++;
3097 ctx->invalid_bitmaps++;
21c84b71 3098 }
f3db3566
TT
3099 return 0;
3100 }
d7cca6b0
VAH
3101 if ((blk >= ext2fs_inode_table_loc(fs, i)) &&
3102 (blk < (ext2fs_inode_table_loc(fs, i) +
f3db3566 3103 fs->inode_blocks_per_group))) {
21c84b71
TT
3104 /*
3105 * If there are bad blocks in the inode table,
3106 * the inode scan code will try to do
3107 * something reasonable automatically.
3108 */
f3db3566
TT
3109 return 0;
3110 }
8039c480 3111 first_block += fs->super->s_blocks_per_group;
f3db3566
TT
3112 }
3113 /*
3114 * If we've gotten to this point, then the only
3115 * possibility is that the bad block inode meta data
3116 * is using a bad block.
3117 */
3118 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
000ba404
TT
3119 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
3120 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
3121 p->bbcheck = 1;
3122 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
3123 *block_nr = 0;
3124 return BLOCK_CHANGED;
3125 }
a02ce9df 3126 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301 3127 return BLOCK_ABORT;
f3db3566 3128 return 0;
3839e657 3129 }
1b6bf175
TT
3130
3131 pctx->group = -1;
3132
3133 /* Warn user that the block wasn't claimed */
3134 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
3135
f3db3566 3136 return 0;
3839e657
TT
3137}
3138
3971bfe8 3139static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
c5d2f50d 3140 const char *name, int num, blk64_t *new_block)
3839e657 3141{
1b6bf175 3142 ext2_filsys fs = ctx->fs;
617446e4 3143 dgrp_t last_grp;
c5d2f50d
VAH
3144 blk64_t old_block = *new_block;
3145 blk64_t last_block;
3971bfe8
TT
3146 dgrp_t flexbg;
3147 unsigned flexbg_size;
3148 int i, is_flexbg;
3839e657 3149 char *buf;
1b6bf175
TT
3150 struct problem_context pctx;
3151
3152 clear_problem_context(&pctx);
3153
3154 pctx.group = group;
3155 pctx.blk = old_block;
3156 pctx.str = name;
3157
617446e4
TT
3158 /*
3159 * For flex_bg filesystems, first try to allocate the metadata
3160 * within the flex_bg, and if that fails then try finding the
3161 * space anywhere in the filesystem.
3162 */
3163 is_flexbg = EXT2_HAS_INCOMPAT_FEATURE(fs->super,
3164 EXT4_FEATURE_INCOMPAT_FLEX_BG);
3165 if (is_flexbg) {
3166 flexbg_size = 1 << fs->super->s_log_groups_per_flex;
3167 flexbg = group / flexbg_size;
b49f78fe
TT
3168 first_block = ext2fs_group_first_block2(fs,
3169 flexbg_size * flexbg);
617446e4 3170 last_grp = group | (flexbg_size - 1);
b4f724c8
DW
3171 if (last_grp >= fs->group_desc_count)
3172 last_grp = fs->group_desc_count - 1;
b49f78fe 3173 last_block = ext2fs_group_last_block2(fs, last_grp);
617446e4 3174 } else
b49f78fe 3175 last_block = ext2fs_group_last_block2(fs, group);
c5d2f50d
VAH
3176 pctx.errcode = ext2fs_get_free_blocks2(fs, first_block, last_block,
3177 num, ctx->block_found_map,
3178 new_block);
617446e4 3179 if (is_flexbg && (pctx.errcode == EXT2_ET_BLOCK_ALLOC_FAIL))
c5d2f50d 3180 pctx.errcode = ext2fs_get_free_blocks2(fs,
617446e4 3181 fs->super->s_first_data_block,
4efbac6f 3182 ext2fs_blocks_count(fs->super),
617446e4 3183 num, ctx->block_found_map, new_block);
1b6bf175
TT
3184 if (pctx.errcode) {
3185 pctx.num = num;
3186 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
3839e657 3187 ext2fs_unmark_valid(fs);
617446e4 3188 ctx->flags |= E2F_FLAG_ABORT;
3839e657
TT
3189 return;
3190 }
c4e3d3f3 3191 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
08b21301 3192 if (pctx.errcode) {
1b6bf175 3193 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
3839e657 3194 ext2fs_unmark_valid(fs);
617446e4 3195 ctx->flags |= E2F_FLAG_ABORT;
3839e657
TT
3196 return;
3197 }
3198 ext2fs_mark_super_dirty(fs);
299d7424 3199 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
1b6bf175
TT
3200 pctx.blk2 = *new_block;
3201 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
3202 PR_1_RELOC_TO), &pctx);
3203 pctx.blk2 = 0;
3839e657 3204 for (i = 0; i < num; i++) {
1b6bf175 3205 pctx.blk = i;
c5d2f50d 3206 ext2fs_mark_block_bitmap2(ctx->block_found_map, (*new_block)+i);
f3db3566 3207 if (old_block) {
24a117ab 3208 pctx.errcode = io_channel_read_blk64(fs->io,
1b6bf175
TT
3209 old_block + i, 1, buf);
3210 if (pctx.errcode)
3211 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
f3db3566
TT
3212 } else
3213 memset(buf, 0, fs->blocksize);
3214
1b6bf175 3215 pctx.blk = (*new_block) + i;
24a117ab 3216 pctx.errcode = io_channel_write_blk64(fs->io, pctx.blk,
3839e657 3217 1, buf);
1b6bf175
TT
3218 if (pctx.errcode)
3219 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
3839e657 3220 }
c4e3d3f3 3221 ext2fs_free_mem(&buf);
3839e657
TT
3222}
3223
3224/*
f3db3566
TT
3225 * This routine gets called at the end of pass 1 if bad blocks are
3226 * detected in the superblock, group descriptors, inode_bitmaps, or
3227 * block bitmaps. At this point, all of the blocks have been mapped
3228 * out, so we can try to allocate new block(s) to replace the bad
3229 * blocks.
3839e657 3230 */
1b6bf175 3231static void handle_fs_bad_blocks(e2fsck_t ctx)
3839e657 3232{
1b6bf175 3233 ext2_filsys fs = ctx->fs;
54434927 3234 dgrp_t i;
c5d2f50d
VAH
3235 blk64_t first_block;
3236 blk64_t new_blk;
3839e657
TT
3237
3238 for (i = 0; i < fs->group_desc_count; i++) {
b49f78fe 3239 first_block = ext2fs_group_first_block2(fs, i);
abf23439 3240
1b6bf175 3241 if (ctx->invalid_block_bitmap_flag[i]) {
c5d2f50d 3242 new_blk = ext2fs_block_bitmap_loc(fs, i);
0c4a0726 3243 new_table_block(ctx, first_block, i, _("block bitmap"),
c5d2f50d
VAH
3244 1, &new_blk);
3245 ext2fs_block_bitmap_loc_set(fs, i, new_blk);
3839e657 3246 }
1b6bf175 3247 if (ctx->invalid_inode_bitmap_flag[i]) {
c5d2f50d 3248 new_blk = ext2fs_inode_bitmap_loc(fs, i);
0c4a0726 3249 new_table_block(ctx, first_block, i, _("inode bitmap"),
c5d2f50d
VAH
3250 1, &new_blk);
3251 ext2fs_inode_bitmap_loc_set(fs, i, new_blk);
3839e657 3252 }
1b6bf175 3253 if (ctx->invalid_inode_table_flag[i]) {
c5d2f50d 3254 new_blk = ext2fs_inode_table_loc(fs, i);
0c4a0726 3255 new_table_block(ctx, first_block, i, _("inode table"),
efc6f628 3256 fs->inode_blocks_per_group,
c5d2f50d
VAH
3257 &new_blk);
3258 ext2fs_inode_table_loc_set(fs, i, new_blk);
08b21301 3259 ctx->flags |= E2F_FLAG_RESTART;
3839e657 3260 }
3839e657 3261 }
1b6bf175 3262 ctx->invalid_bitmaps = 0;
3839e657
TT
3263}
3264
3265/*
3266 * This routine marks all blocks which are used by the superblock,
3267 * group descriptors, inode bitmaps, and block bitmaps.
3268 */
1b6bf175 3269static void mark_table_blocks(e2fsck_t ctx)
3839e657 3270{
1b6bf175 3271 ext2_filsys fs = ctx->fs;
6dc64392 3272 blk64_t b;
54434927 3273 dgrp_t i;
68477355 3274 unsigned int j;
21c84b71 3275 struct problem_context pctx;
efc6f628 3276
21c84b71 3277 clear_problem_context(&pctx);
efc6f628 3278
3839e657 3279 for (i = 0; i < fs->group_desc_count; i++) {
21c84b71 3280 pctx.group = i;
da2e97f7 3281
ef344e13 3282 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
35c8faaf 3283 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_metadata_map);
ef344e13 3284
21c84b71
TT
3285 /*
3286 * Mark the blocks used for the inode table
3287 */
d7cca6b0
VAH
3288 if (ext2fs_inode_table_loc(fs, i)) {
3289 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
21c84b71
TT
3290 j < fs->inode_blocks_per_group;
3291 j++, b++) {
c5d2f50d 3292 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
21c84b71
TT
3293 b)) {
3294 pctx.blk = b;
9a7fe4bd
TT
3295 if (!ctx->invalid_inode_table_flag[i] &&
3296 fix_problem(ctx,
21c84b71 3297 PR_1_ITABLE_CONFLICT, &pctx)) {
1b6bf175
TT
3298 ctx->invalid_inode_table_flag[i]++;
3299 ctx->invalid_bitmaps++;
21c84b71
TT
3300 }
3301 } else {
35c8faaf
DW
3302 ext2fs_mark_block_bitmap2(
3303 ctx->block_found_map, b);
3304 ext2fs_mark_block_bitmap2(
3305 ctx->block_metadata_map, b);
21c84b71
TT
3306 }
3307 }
3308 }
efc6f628 3309
3839e657 3310 /*
efc6f628 3311 * Mark block used for the block bitmap
3839e657 3312 */
d7cca6b0 3313 if (ext2fs_block_bitmap_loc(fs, i)) {
c5d2f50d 3314 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
d7cca6b0
VAH
3315 ext2fs_block_bitmap_loc(fs, i))) {
3316 pctx.blk = ext2fs_block_bitmap_loc(fs, i);
1b6bf175
TT
3317 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
3318 ctx->invalid_block_bitmap_flag[i]++;
3319 ctx->invalid_bitmaps++;
f3db3566 3320 }
50e1e10f 3321 } else {
c5d2f50d 3322 ext2fs_mark_block_bitmap2(ctx->block_found_map,
d7cca6b0 3323 ext2fs_block_bitmap_loc(fs, i));
35c8faaf
DW
3324 ext2fs_mark_block_bitmap2(ctx->block_metadata_map,
3325 ext2fs_block_bitmap_loc(fs, i));
3326 }
f3db3566 3327 }
3839e657 3328 /*
efc6f628 3329 * Mark block used for the inode bitmap
3839e657 3330 */
d7cca6b0 3331 if (ext2fs_inode_bitmap_loc(fs, i)) {
c5d2f50d 3332 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
d7cca6b0
VAH
3333 ext2fs_inode_bitmap_loc(fs, i))) {
3334 pctx.blk = ext2fs_inode_bitmap_loc(fs, i);
1b6bf175
TT
3335 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
3336 ctx->invalid_inode_bitmap_flag[i]++;
3337 ctx->invalid_bitmaps++;
efc6f628 3338 }
50e1e10f 3339 } else {
35c8faaf
DW
3340 ext2fs_mark_block_bitmap2(ctx->block_metadata_map,
3341 ext2fs_inode_bitmap_loc(fs, i));
c5d2f50d 3342 ext2fs_mark_block_bitmap2(ctx->block_found_map,
d7cca6b0 3343 ext2fs_inode_bitmap_loc(fs, i));
50e1e10f 3344 }
f3db3566 3345 }
3839e657
TT
3346 }
3347}
efc6f628 3348
3839e657 3349/*
e72a9ba3 3350 * Thes subroutines short circuits ext2fs_get_blocks and
3839e657
TT
3351 * ext2fs_check_directory; we use them since we already have the inode
3352 * structure, so there's no point in letting the ext2fs library read
3353 * the inode again.
3354 */
86c627ec
TT
3355static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
3356 blk_t *blocks)
3839e657 3357{
54dc7ca2 3358 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3839e657 3359 int i;
efc6f628 3360
71d521c6 3361 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
521e3685
TT
3362 return EXT2_ET_CALLBACK_NOTHANDLED;
3363
3364 for (i=0; i < EXT2_N_BLOCKS; i++)
1b6bf175 3365 blocks[i] = ctx->stashed_inode->i_block[i];
521e3685 3366 return 0;
3839e657
TT
3367}
3368
86c627ec 3369static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
e72a9ba3 3370 struct ext2_inode *inode)
1e3472c5 3371{
54dc7ca2 3372 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 3373
71d521c6 3374 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1e3472c5 3375 return EXT2_ET_CALLBACK_NOTHANDLED;
1b6bf175 3376 *inode = *ctx->stashed_inode;
1e3472c5
TT
3377 return 0;
3378}
3379
86c627ec 3380static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
1e3472c5
TT
3381 struct ext2_inode *inode)
3382{
54dc7ca2 3383 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 3384
27431595
TT
3385 if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
3386 (inode != ctx->stashed_inode))
1b6bf175 3387 *ctx->stashed_inode = *inode;
1e3472c5
TT
3388 return EXT2_ET_CALLBACK_NOTHANDLED;
3389}
3390
86c627ec 3391static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
3839e657 3392{
54dc7ca2 3393 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 3394
71d521c6 3395 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1b6bf175
TT
3396 return EXT2_ET_CALLBACK_NOTHANDLED;
3397
3398 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
291c9049 3399 return EXT2_ET_NO_DIRECTORY;
1b6bf175 3400 return 0;
3839e657 3401}
e72a9ba3 3402
16bd349e
TT
3403static errcode_t e2fsck_get_alloc_block(ext2_filsys fs, blk64_t goal,
3404 blk64_t *ret)
3405{
3406 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3407 errcode_t retval;
c5d2f50d 3408 blk64_t new_block;
16bd349e
TT
3409
3410 if (ctx->block_found_map) {
28843200
TT
3411 retval = ext2fs_new_block2(fs, goal, ctx->block_found_map,
3412 &new_block);
16bd349e
TT
3413 if (retval)
3414 return retval;
8a2cbe2c 3415 if (fs->block_map) {
2d07b3ad 3416 ext2fs_mark_block_bitmap2(fs->block_map, new_block);
8a2cbe2c
TT
3417 ext2fs_mark_bb_dirty(fs);
3418 }
16bd349e
TT
3419 } else {
3420 if (!fs->block_map) {
3421 retval = ext2fs_read_block_bitmap(fs);
3422 if (retval)
3423 return retval;
3424 }
3425
28843200 3426 retval = ext2fs_new_block2(fs, goal, 0, &new_block);
16bd349e
TT
3427 if (retval)
3428 return retval;
3429 }
efc6f628 3430
16bd349e
TT
3431 *ret = new_block;
3432 return (0);
3433}
3434
3435static void e2fsck_block_alloc_stats(ext2_filsys fs, blk64_t blk, int inuse)
3436{
3437 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3438
409f3884
DW
3439 /* Never free a critical metadata block */
3440 if (ctx->block_found_map &&
3441 ctx->block_metadata_map &&
3442 inuse < 0 &&
3443 ext2fs_test_block_bitmap2(ctx->block_metadata_map, blk))
3444 return;
3445
16bd349e
TT
3446 if (ctx->block_found_map) {
3447 if (inuse > 0)
28843200 3448 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
16bd349e 3449 else
28843200 3450 ext2fs_unmark_block_bitmap2(ctx->block_found_map, blk);
16bd349e
TT
3451 }
3452}
3453
2d2abcc6 3454void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts)
e72a9ba3
TT
3455{
3456 ext2_filsys fs = ctx->fs;
3457
2d2abcc6 3458 if (use_shortcuts) {
e72a9ba3
TT
3459 fs->get_blocks = pass1_get_blocks;
3460 fs->check_directory = pass1_check_directory;
3461 fs->read_inode = pass1_read_inode;
3462 fs->write_inode = pass1_write_inode;
3463 ctx->stashed_ino = 0;
3464 } else {
3465 fs->get_blocks = 0;
3466 fs->check_directory = 0;
3467 fs->read_inode = 0;
3468 fs->write_inode = 0;
3469 }
3470}
b4a40883
DW
3471
3472void e2fsck_intercept_block_allocations(e2fsck_t ctx)
3473{
3474 ext2fs_set_alloc_block_callback(ctx->fs, e2fsck_get_alloc_block, 0);
3475 ext2fs_set_block_alloc_stats_callback(ctx->fs,
3476 e2fsck_block_alloc_stats, 0);
3477}