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