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