]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - e2fsck/pass1.c
debugfs, e2fsck: fix s_desc_size handling
[thirdparty/e2fsprogs.git] / e2fsck / pass1.c
CommitLineData
3839e657
TT
1/*
2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
efc6f628 3 *
21c84b71
TT
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
efc6f628 10 *
3839e657
TT
11 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
12 * and applies the following tests to each inode:
13 *
14 * - The mode field of the inode must be legal.
15 * - The size and block count fields of the inode are correct.
16 * - A data block must not be used by another inode
17 *
18 * Pass 1 also gathers the collects the following information:
19 *
20 * - A bitmap of which inodes are in use. (inode_used_map)
21 * - A bitmap of which inodes are directories. (inode_dir_map)
aa4115a4 22 * - A bitmap of which inodes are regular files. (inode_reg_map)
3839e657 23 * - A bitmap of which inodes have bad fields. (inode_bad_map)
21c84b71 24 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
aa4115a4 25 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
3839e657
TT
26 * - A bitmap of which blocks are in use. (block_found_map)
27 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
28 * - The data blocks of the directory inodes. (dir_map)
29 *
30 * Pass 1 is designed to stash away enough information so that the
31 * other passes should not need to read in the inode information
32 * during the normal course of a filesystem check. (Althogh if an
33 * inconsistency is detected, other passes may need to read in an
34 * inode to fix it.)
35 *
36 * Note that pass 1B will be invoked if there are any duplicate blocks
37 * found.
38 */
39
b969b1b8 40#define _GNU_SOURCE 1 /* get strnlen() */
d1154eb4 41#include "config.h"
3e699064 42#include <string.h>
3839e657 43#include <time.h>
50e1e10f
TT
44#ifdef HAVE_ERRNO_H
45#include <errno.h>
46#endif
3839e657 47
3839e657 48#include "e2fsck.h"
342d847d
TT
49#include <ext2fs/ext2_ext_attr.h>
50
21c84b71 51#include "problem.h"
3839e657 52
50e1e10f
TT
53#ifdef NO_INLINE_FUNCS
54#define _INLINE_
55#else
56#define _INLINE_ inline
57#endif
58
6dc64392
VAH
59static int process_block(ext2_filsys fs, blk64_t *blocknr,
60 e2_blkcnt_t blockcnt, blk64_t ref_blk,
54dc7ca2 61 int ref_offset, void *priv_data);
6dc64392
VAH
62static int process_bad_block(ext2_filsys fs, blk64_t *block_nr,
63 e2_blkcnt_t blockcnt, blk64_t ref_blk,
54dc7ca2 64 int ref_offset, void *priv_data);
1b6bf175 65static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657 66 char *block_buf);
1b6bf175 67static void mark_table_blocks(e2fsck_t ctx);
1b6bf175 68static void alloc_bb_map(e2fsck_t ctx);
aa4115a4 69static void alloc_imagic_map(e2fsck_t ctx);
fdbdea09 70static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
1b6bf175
TT
71static void handle_fs_bad_blocks(e2fsck_t ctx);
72static void process_inodes(e2fsck_t ctx, char *block_buf);
4c77fe50 73static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
f3db3566 74static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
54dc7ca2 75 dgrp_t group, void * priv_data);
efc6f628 76static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
e8a3ee62 77 char *block_buf, int adjust_sign);
6dc64392 78/* static char *describe_illegal_block(ext2_filsys fs, blk64_t block); */
3839e657
TT
79
80struct process_block_struct {
86c627ec 81 ext2_ino_t ino;
83e692e8 82 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
000ba404 83 fragmented:1, compressed:1, bbcheck:1;
65d71894 84 blk64_t num_blocks;
6dc64392 85 blk64_t max_blocks;
9d1bd3de 86 e2_blkcnt_t last_block;
010dc7b9 87 e2_blkcnt_t last_init_lblock;
4dbe79bc 88 e2_blkcnt_t last_db_block;
246501c6 89 int num_illegal_blocks;
6dc64392 90 blk64_t previous_block;
f3db3566 91 struct ext2_inode *inode;
21c84b71 92 struct problem_context *pctx;
000ba404 93 ext2fs_block_bitmap fs_meta_blocks;
1b6bf175 94 e2fsck_t ctx;
3839e657
TT
95};
96
97struct process_inode_block {
86c627ec 98 ext2_ino_t ino;
3839e657
TT
99 struct ext2_inode inode;
100};
101
f8188fff
TT
102struct scan_callback_struct {
103 e2fsck_t ctx;
104 char *block_buf;
105};
106
3839e657
TT
107/*
108 * For the inodes to process list.
109 */
110static struct process_inode_block *inodes_to_process;
111static int process_inode_count;
3839e657 112
7823dd65
TT
113static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
114 EXT2_MIN_BLOCK_LOG_SIZE + 1];
246501c6 115
f3db3566
TT
116/*
117 * Free all memory allocated by pass1 in preparation for restarting
118 * things.
119 */
54434927 120static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
f3db3566 121{
c4e3d3f3 122 ext2fs_free_mem(&inodes_to_process);
08b21301 123 inodes_to_process = 0;
f3db3566
TT
124}
125
7cf73dcd
TT
126/*
127 * Check to make sure a device inode is real. Returns 1 if the device
128 * checks out, 0 if not.
1dde43f0
TT
129 *
130 * Note: this routine is now also used to check FIFO's and Sockets,
131 * since they have the same requirement; the i_block fields should be
efc6f628 132 * zero.
7cf73dcd 133 */
efc6f628 134int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
f954ba01 135 struct ext2_inode *inode)
7cf73dcd
TT
136{
137 int i;
138
a40ecbb1 139 /*
441ab1e0
TT
140 * If the index flag is set, then this is a bogus
141 * device/fifo/socket
a40ecbb1 142 */
441ab1e0 143 if (inode->i_flags & EXT2_INDEX_FL)
53abed0a 144 return 0;
bcf9c5d4 145
7fdfabd3
TT
146 /*
147 * We should be able to do the test below all the time, but
148 * because the kernel doesn't forcibly clear the device
149 * inode's additional i_block fields, there are some rare
150 * occasions when a legitimate device inode will have non-zero
151 * additional i_block fields. So for now, we only complain
152 * when the immutable flag is set, which should never happen
153 * for devices. (And that's when the problem is caused, since
154 * you can't set or clear immutable flags for devices.) Once
155 * the kernel has been fixed we can change this...
156 */
01fbc701 157 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
efc6f628 158 for (i=4; i < EXT2_N_BLOCKS; i++)
7fdfabd3
TT
159 if (inode->i_block[i])
160 return 0;
161 }
7cf73dcd
TT
162 return 1;
163}
164
67052a8a
AD
165/*
166 * Check to make sure a symlink inode is real. Returns 1 if the symlink
167 * checks out, 0 if not.
168 */
7cadc577
TT
169int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
170 struct ext2_inode *inode, char *buf)
67052a8a 171{
54434927 172 unsigned int len;
d007cb4c 173 int i;
6dc64392 174 blk64_t blocks;
7cadc577
TT
175 ext2_extent_handle_t handle;
176 struct ext2_extent_info info;
177 struct ext2fs_extent extent;
67052a8a 178
bcf9c5d4
TT
179 if ((inode->i_size_high || inode->i_size == 0) ||
180 (inode->i_flags & EXT2_INDEX_FL))
67052a8a
AD
181 return 0;
182
7cadc577
TT
183 if (inode->i_flags & EXT4_EXTENTS_FL) {
184 if (inode->i_size > fs->blocksize)
185 return 0;
84b239ae 186 if (ext2fs_extent_open2(fs, ino, inode, &handle))
7cadc577
TT
187 return 0;
188 i = 0;
189 if (ext2fs_extent_get_info(handle, &info) ||
190 (info.num_entries != 1) ||
191 (info.max_depth != 0))
192 goto exit_extent;
193 if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent) ||
194 (extent.e_lblk != 0) ||
195 (extent.e_len != 1) ||
196 (extent.e_pblk < fs->super->s_first_data_block) ||
4efbac6f 197 (extent.e_pblk >= ext2fs_blocks_count(fs->super)))
7cadc577
TT
198 goto exit_extent;
199 i = 1;
200 exit_extent:
201 ext2fs_extent_free(handle);
202 return i;
203 }
204
6dc64392 205 blocks = ext2fs_inode_data_blocks2(fs, inode);
0684a4f3 206 if (blocks) {
b94a052a 207 if ((inode->i_size >= fs->blocksize) ||
0684a4f3 208 (blocks != fs->blocksize >> 9) ||
d007cb4c 209 (inode->i_block[0] < fs->super->s_first_data_block) ||
4efbac6f 210 (inode->i_block[0] >= ext2fs_blocks_count(fs->super)))
67052a8a
AD
211 return 0;
212
213 for (i = 1; i < EXT2_N_BLOCKS; i++)
214 if (inode->i_block[i])
215 return 0;
b94a052a 216
24a117ab 217 if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf))
b94a052a
AD
218 return 0;
219
220 len = strnlen(buf, fs->blocksize);
221 if (len == fs->blocksize)
222 return 0;
67052a8a 223 } else {
b94a052a 224 if (inode->i_size >= sizeof(inode->i_block))
67052a8a
AD
225 return 0;
226
b94a052a
AD
227 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
228 if (len == sizeof(inode->i_block))
67052a8a
AD
229 return 0;
230 }
b94a052a
AD
231 if (len != inode->i_size)
232 return 0;
67052a8a
AD
233 return 1;
234}
235
6fdc7a32 236/*
01fbc701
TT
237 * If the immutable (or append-only) flag is set on the inode, offer
238 * to clear it.
6fdc7a32 239 */
bcf9c5d4 240#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
6fdc7a32
TT
241static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
242{
b94a052a 243 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
6fdc7a32
TT
244 return;
245
246 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
247 return;
248
b94a052a 249 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
6fdc7a32
TT
250 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
251}
252
d647a1ea
TT
253/*
254 * If device, fifo or socket, check size is zero -- if not offer to
255 * clear it
256 */
257static void check_size(e2fsck_t ctx, struct problem_context *pctx)
258{
259 struct ext2_inode *inode = pctx->inode;
efc6f628 260
0bd0e593 261 if (EXT2_I_SIZE(inode) == 0)
d647a1ea 262 return;
efc6f628 263
85645a6f 264 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
d647a1ea 265 return;
efc6f628 266
d647a1ea 267 inode->i_size = 0;
fdbdea09 268 inode->i_size_high = 0;
d647a1ea
TT
269 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
270}
efc6f628 271
cebe48a1
TT
272static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
273{
274 struct ext2_super_block *sb = ctx->fs->super;
275 struct ext2_inode_large *inode;
276 struct ext2_ext_attr_entry *entry;
e3507739 277 char *start;
1a8c2c4a 278 unsigned int storage_size, remain;
3c7c6d73 279 problem_t problem = 0;
cebe48a1
TT
280
281 inode = (struct ext2_inode_large *) pctx->inode;
282 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
283 inode->i_extra_isize;
284 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
285 inode->i_extra_isize + sizeof(__u32);
cebe48a1
TT
286 entry = (struct ext2_ext_attr_entry *) start;
287
288 /* scan all entry's headers first */
289
290 /* take finish entry 0UL into account */
efc6f628 291 remain = storage_size - sizeof(__u32);
cebe48a1
TT
292
293 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
fefaef39 294 __u32 hash;
cebe48a1
TT
295
296 /* header eats this space */
297 remain -= sizeof(struct ext2_ext_attr_entry);
efc6f628 298
cebe48a1
TT
299 /* is attribute name valid? */
300 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
301 pctx->num = entry->e_name_len;
302 problem = PR_1_ATTR_NAME_LEN;
303 goto fix;
304 }
305
306 /* attribute len eats this space */
307 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
308
309 /* check value size */
10fc3a63 310 if (entry->e_value_size > remain) {
cebe48a1
TT
311 pctx->num = entry->e_value_size;
312 problem = PR_1_ATTR_VALUE_SIZE;
313 goto fix;
314 }
315
cebe48a1
TT
316 /* e_value_block must be 0 in inode's ea */
317 if (entry->e_value_block != 0) {
318 pctx->num = entry->e_value_block;
319 problem = PR_1_ATTR_VALUE_BLOCK;
320 goto fix;
321 }
fefaef39
AD
322
323 hash = ext2fs_ext_attr_hash_entry(entry,
324 start + entry->e_value_offs);
325
326 /* e_hash may be 0 in older inode's ea */
327 if (entry->e_hash != 0 && entry->e_hash != hash) {
cebe48a1
TT
328 pctx->num = entry->e_hash;
329 problem = PR_1_ATTR_HASH;
330 goto fix;
331 }
332
333 remain -= entry->e_value_size;
cebe48a1
TT
334
335 entry = EXT2_EXT_ATTR_NEXT(entry);
336 }
337fix:
338 /*
339 * it seems like a corruption. it's very unlikely we could repair
340 * EA(s) in automatic fashion -bzzz
341 */
cebe48a1
TT
342 if (problem == 0 || !fix_problem(ctx, problem, pctx))
343 return;
344
fefaef39 345 /* simply remove all possible EA(s) */
cebe48a1 346 *((__u32 *)start) = 0UL;
da938f20 347 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
cebe48a1
TT
348 EXT2_INODE_SIZE(sb), "pass1");
349}
350
351static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
352{
353 struct ext2_super_block *sb = ctx->fs->super;
354 struct ext2_inode_large *inode;
355 __u32 *eamagic;
356 int min, max;
357
358 inode = (struct ext2_inode_large *) pctx->inode;
359 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
360 /* this isn't large inode. so, nothing to check */
361 return;
362 }
363
364#if 0
365 printf("inode #%u, i_extra_size %d\n", pctx->ino,
366 inode->i_extra_isize);
efc6f628 367#endif
89efc88e
TT
368 /* i_extra_isize must cover i_extra_isize + i_checksum_hi at least */
369 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_checksum_hi);
cebe48a1 370 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
efc6f628 371 /*
cebe48a1
TT
372 * For now we will allow i_extra_isize to be 0, but really
373 * implementations should never allow i_extra_isize to be 0
374 */
375 if (inode->i_extra_isize &&
376 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
377 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
378 return;
379 inode->i_extra_isize = min;
380 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
381 EXT2_INODE_SIZE(sb), "pass1");
382 return;
383 }
384
385 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
386 inode->i_extra_isize);
387 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
388 /* it seems inode has an extended attribute(s) in body */
389 check_ea_in_inode(ctx, pctx);
390 }
391}
6fdc7a32 392
efc6f628 393/*
fbc3f901
TT
394 * Check to see if the inode might really be a directory, despite i_mode
395 *
396 * This is a lot of complexity for something for which I'm not really
397 * convinced happens frequently in the wild. If for any reason this
398 * causes any problems, take this code out.
399 * [tytso:20070331.0827EDT]
400 */
401static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
402 char *buf)
403{
404 struct ext2_inode *inode = pctx->inode;
fbc3f901 405 struct ext2_dir_entry *dirent;
e94bc631 406 errcode_t retval;
cf5301d7 407 blk64_t blk;
03fa6f8a 408 unsigned int i, rec_len, not_device = 0;
1ec42a00 409 int extent_fs;
fbc3f901 410
1ec42a00
ND
411 /*
412 * If the mode looks OK, we believe it. If the first block in
413 * the i_block array is 0, this cannot be a directory. If the
414 * inode is extent-mapped, it is still the case that the latter
415 * cannot be 0 - the magic number in the extent header would make
416 * it nonzero.
417 */
fbc3f901 418 if (LINUX_S_ISDIR(inode->i_mode) || LINUX_S_ISREG(inode->i_mode) ||
0eeb1549 419 LINUX_S_ISLNK(inode->i_mode) || inode->i_block[0] == 0)
fbc3f901
TT
420 return;
421
1ec42a00
ND
422 /*
423 * Check the block numbers in the i_block array for validity:
424 * zero blocks are skipped (but the first one cannot be zero -
425 * see above), other blocks are checked against the first and
426 * max data blocks (from the the superblock) and against the
427 * block bitmap. Any invalid block found means this cannot be
428 * a directory.
429 *
430 * If there are non-zero blocks past the fourth entry, then
431 * this cannot be a device file: we remember that for the next
432 * check.
433 *
434 * For extent mapped files, we don't do any sanity checking:
435 * just try to get the phys block of logical block 0 and run
436 * with it.
437 */
438
cf5301d7
AD
439 extent_fs = (ctx->fs->super->s_feature_incompat &
440 EXT3_FEATURE_INCOMPAT_EXTENTS);
1ec42a00
ND
441 if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {
442 /* extent mapped */
6dc64392 443 if (ext2fs_bmap2(ctx->fs, pctx->ino, inode, 0, 0, 0, 0,
1ec42a00
ND
444 &blk))
445 return;
446 /* device files are never extent mapped */
447 not_device++;
448 } else {
449 for (i=0; i < EXT2_N_BLOCKS; i++) {
450 blk = inode->i_block[i];
451 if (!blk)
452 continue;
453 if (i >= 4)
454 not_device++;
455
456 if (blk < ctx->fs->super->s_first_data_block ||
cc84d866
TT
457 blk >= ext2fs_blocks_count(ctx->fs->super) ||
458 ext2fs_fast_test_block_bitmap2(ctx->block_found_map,
459 blk))
1ec42a00
ND
460 return; /* Invalid block, can't be dir */
461 }
462 blk = inode->i_block[0];
fbc3f901
TT
463 }
464
1ec42a00
ND
465 /*
466 * If the mode says this is a device file and the i_links_count field
467 * is sane and we have not ruled it out as a device file previously,
468 * we declare it a device file, not a directory.
469 */
efc6f628 470 if ((LINUX_S_ISCHR(inode->i_mode) || LINUX_S_ISBLK(inode->i_mode)) &&
fbc3f901
TT
471 (inode->i_links_count == 1) && !not_device)
472 return;
473
1ec42a00 474 /* read the first block */
f85a9ae6 475 ehandler_operation(_("reading directory block"));
6dc64392 476 retval = ext2fs_read_dir_block3(ctx->fs, blk, buf, 0);
e94bc631
TT
477 ehandler_operation(0);
478 if (retval)
fbc3f901
TT
479 return;
480
481 dirent = (struct ext2_dir_entry *) buf;
8a480350
TT
482 retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
483 if (retval)
484 return;
fbc3f901
TT
485 if (((dirent->name_len & 0xFF) != 1) ||
486 (dirent->name[0] != '.') ||
487 (dirent->inode != pctx->ino) ||
5dd77dbe
TT
488 (rec_len < 12) ||
489 (rec_len % 4) ||
490 (rec_len >= ctx->fs->blocksize - 12))
fbc3f901
TT
491 return;
492
5dd77dbe 493 dirent = (struct ext2_dir_entry *) (buf + rec_len);
8a480350
TT
494 retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
495 if (retval)
496 return;
fbc3f901
TT
497 if (((dirent->name_len & 0xFF) != 2) ||
498 (dirent->name[0] != '.') ||
499 (dirent->name[1] != '.') ||
5dd77dbe
TT
500 (rec_len < 12) ||
501 (rec_len % 4))
fbc3f901
TT
502 return;
503
504 if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
505 inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
efc6f628
TT
506 e2fsck_write_inode_full(ctx, pctx->ino, inode,
507 EXT2_INODE_SIZE(ctx->fs->super),
fbc3f901
TT
508 "check_is_really_dir");
509 }
510}
511
f404167d
TT
512void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
513 ext2_icount_t *ret)
34b9f796 514{
f954ba01 515 unsigned int threshold;
34b9f796
TT
516 ext2_ino_t num_dirs;
517 errcode_t retval;
f954ba01
TT
518 char *tdb_dir;
519 int enable;
34b9f796
TT
520
521 *ret = 0;
522
523 profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
524 &tdb_dir);
f954ba01
TT
525 profile_get_uint(ctx->profile, "scratch_files",
526 "numdirs_threshold", 0, 0, &threshold);
34b9f796
TT
527 profile_get_boolean(ctx->profile, "scratch_files",
528 "icount", 0, 1, &enable);
529
530 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
531 if (retval)
532 num_dirs = 1024; /* Guess */
533
534 if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
535 (threshold && num_dirs <= threshold))
536 return;
537
538 retval = ext2fs_create_icount_tdb(ctx->fs, tdb_dir, flags, ret);
539 if (retval)
540 *ret = 0;
541}
542
08b21301 543void e2fsck_pass1(e2fsck_t ctx)
3839e657 544{
9d1bd3de 545 int i;
31e29a12 546 __u64 max_sizes;
1b6bf175 547 ext2_filsys fs = ctx->fs;
24c91184 548 ext2_ino_t ino = 0;
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 }
3b6c0938
DW
2166 if (LINUX_S_ISREG(inode->i_mode) &&
2167 ext2fs_needs_large_file_feature(EXT2_I_SIZE(inode)))
246501c6 2168 ctx->large_files++;
8a8f3654 2169 if ((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) ||
1ca1059f
TT
2170 ((fs->super->s_feature_ro_compat &
2171 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
2172 (inode->i_flags & EXT4_HUGE_FILE_FL) &&
2173 (inode->osd2.linux2.l_i_blocks_hi != 0))) {
21c84b71 2174 pctx->num = pb.num_blocks;
1b6bf175 2175 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
3839e657 2176 inode->i_blocks = pb.num_blocks;
b70506bf 2177 inode->osd2.linux2.l_i_blocks_hi = pb.num_blocks >> 32;
503f9e7f 2178 dirty_inode++;
21c84b71
TT
2179 }
2180 pctx->num = 0;
3839e657 2181 }
a49249d2
TT
2182
2183 if (ctx->dirs_to_hash && pb.is_dir &&
2184 !(inode->i_flags & EXT2_INDEX_FL) &&
2185 ((inode->i_size / fs->blocksize) >= 3))
2186 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
2187
503f9e7f
TT
2188out:
2189 if (dirty_inode)
2190 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
50e1e10f
TT
2191}
2192
21c84b71 2193#if 0
50e1e10f
TT
2194/*
2195 * Helper function called by process block when an illegal block is
2196 * found. It returns a description about why the block is illegal
2197 */
6dc64392 2198static char *describe_illegal_block(ext2_filsys fs, blk64_t block)
50e1e10f 2199{
6dc64392 2200 blk64_t super;
50e1e10f
TT
2201 int i;
2202 static char problem[80];
2203
2204 super = fs->super->s_first_data_block;
2205 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
2206 if (block < super) {
2207 sprintf(problem, "< FIRSTBLOCK (%u)", super);
2208 return(problem);
4efbac6f
VAH
2209 } else if (block >= ext2fs_blocks_count(fs->super)) {
2210 sprintf(problem, "> BLOCKS (%u)", ext2fs_blocks_count(fs->super));
50e1e10f
TT
2211 return(problem);
2212 }
2213 for (i = 0; i < fs->group_desc_count; i++) {
2214 if (block == super) {
2215 sprintf(problem, "is the superblock in group %d", i);
2216 break;
2217 }
2218 if (block > super &&
2219 block <= (super + fs->desc_blocks)) {
2220 sprintf(problem, "is in the group descriptors "
2221 "of group %d", i);
2222 break;
2223 }
d7cca6b0 2224 if (block == ext2fs_block_bitmap_loc(fs, i)) {
50e1e10f
TT
2225 sprintf(problem, "is the block bitmap of group %d", i);
2226 break;
2227 }
d7cca6b0 2228 if (block == ext2fs_inode_bitmap_loc(fs, i)) {
50e1e10f
TT
2229 sprintf(problem, "is the inode bitmap of group %d", i);
2230 break;
2231 }
d7cca6b0
VAH
2232 if (block >= ext2fs_inode_table_loc(fs, i) &&
2233 (block < ext2fs_inode_table_loc(fs, i)
50e1e10f
TT
2234 + fs->inode_blocks_per_group)) {
2235 sprintf(problem, "is in the inode table of group %d",
2236 i);
2237 break;
2238 }
2239 super += fs->super->s_blocks_per_group;
2240 }
2241 return(problem);
2242}
21c84b71 2243#endif
3839e657
TT
2244
2245/*
2246 * This is a helper function for check_blocks().
2247 */
53ef44c4 2248static int process_block(ext2_filsys fs,
6dc64392 2249 blk64_t *block_nr,
9d1bd3de 2250 e2_blkcnt_t blockcnt,
6dc64392 2251 blk64_t ref_block EXT2FS_ATTR((unused)),
54434927 2252 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 2253 void *priv_data)
3839e657
TT
2254{
2255 struct process_block_struct *p;
21c84b71 2256 struct problem_context *pctx;
6dc64392 2257 blk64_t blk = *block_nr;
50e1e10f 2258 int ret_code = 0;
3c7c6d73 2259 problem_t problem = 0;
1b6bf175 2260 e2fsck_t ctx;
3839e657 2261
54dc7ca2 2262 p = (struct process_block_struct *) priv_data;
21c84b71 2263 pctx = p->pctx;
1b6bf175 2264 ctx = p->ctx;
3839e657 2265
1917875f
TT
2266 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
2267 /* todo: Check that the comprblk_fl is high, that the
2268 blkaddr pattern looks right (all non-holes up to
2269 first EXT2FS_COMPRESSED_BLKADDR, then all
2270 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
2271 that the feature_incompat bit is high, and that the
2272 inode is a regular file. If we're doing a "full
2273 check" (a concept introduced to e2fsck by e2compr,
2274 meaning that we look at data blocks as well as
2275 metadata) then call some library routine that
2276 checks the compressed data. I'll have to think
2277 about this, because one particularly important
2278 problem to be able to fix is to recalculate the
2279 cluster size if necessary. I think that perhaps
2280 we'd better do most/all e2compr-specific checks
2281 separately, after the non-e2compr checks. If not
2282 doing a full check, it may be useful to test that
2283 the personality is linux; e.g. if it isn't then
2284 perhaps this really is just an illegal block. */
2285 return 0;
2286 }
b94a052a 2287
4dbe79bc 2288 if (blk == 0)
50e1e10f 2289 return 0;
50e1e10f 2290
3839e657 2291#if 0
50e1e10f 2292 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
3839e657 2293 blockcnt);
50e1e10f 2294#endif
efc6f628 2295
74becf3c
TT
2296 /*
2297 * Simplistic fragmentation check. We merely require that the
2298 * file be contiguous. (Which can never be true for really
2299 * big files that are greater than a block group.)
2300 */
63b5e354
TT
2301 if (!HOLE_BLKADDR(p->previous_block) && p->ino != EXT2_RESIZE_INO) {
2302 if (p->previous_block+1 != blk) {
100d4701
TT
2303 if (ctx->options & E2F_OPT_FRAGCHECK) {
2304 char type = '?';
2305
2306 if (p->is_dir)
2307 type = 'd';
2308 else if (p->is_reg)
2309 type = 'f';
2310
2311 printf(_("%6lu(%c): expecting %6lu "
2312 "got phys %6lu (blkcnt %lld)\n"),
2313 (unsigned long) pctx->ino, type,
63b5e354
TT
2314 (unsigned long) p->previous_block+1,
2315 (unsigned long) blk,
f4e2c991 2316 blockcnt);
100d4701 2317 }
74becf3c 2318 p->fragmented = 1;
63b5e354 2319 }
74becf3c 2320 }
503f9e7f 2321
8421fb67 2322 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
da307041
TT
2323 problem = PR_1_TOOBIG_DIR;
2324 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
2325 problem = PR_1_TOOBIG_REG;
2326 if (!p->is_dir && !p->is_reg && blockcnt > 0)
2327 problem = PR_1_TOOBIG_SYMLINK;
efc6f628 2328
50e1e10f 2329 if (blk < fs->super->s_first_data_block ||
4efbac6f 2330 blk >= ext2fs_blocks_count(fs->super))
21c84b71 2331 problem = PR_1_ILLEGAL_BLOCK_NUM;
21c84b71
TT
2332
2333 if (problem) {
f3db3566 2334 p->num_illegal_blocks++;
21c84b71 2335 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
1b6bf175 2336 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
f3db3566
TT
2337 p->clear = 1;
2338 return BLOCK_ABORT;
2339 }
f8188fff 2340 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
f3db3566 2341 p->suppress = 1;
1b6bf175
TT
2342 set_latch_flags(PR_LATCH_BLOCK,
2343 PRL_SUPPRESS, 0);
f3db3566
TT
2344 }
2345 }
21c84b71
TT
2346 pctx->blk = blk;
2347 pctx->blkcount = blockcnt;
1b6bf175 2348 if (fix_problem(ctx, problem, pctx)) {
50e1e10f
TT
2349 blk = *block_nr = 0;
2350 ret_code = BLOCK_CHANGED;
2351 goto mark_dir;
21c84b71 2352 } else
3839e657 2353 return 0;
3839e657
TT
2354 }
2355
d323f8fb 2356 if (p->ino == EXT2_RESIZE_INO) {
efc6f628 2357 /*
c3ffaf83
TT
2358 * The resize inode has already be sanity checked
2359 * during pass #0 (the superblock checks). All we
2360 * have to do is mark the double indirect block as
2361 * being in use; all of the other blocks are handled
2362 * by mark_table_blocks()).
2363 */
2364 if (blockcnt == BLOCK_COUNT_DIND)
d323f8fb 2365 mark_block_used(ctx, blk);
95a7f15f
TT
2366 p->num_blocks++;
2367 } else if (!(ctx->fs->cluster_ratio_bits &&
2368 p->previous_block &&
2369 (EXT2FS_B2C(ctx->fs, blk) ==
2370 EXT2FS_B2C(ctx->fs, p->previous_block)) &&
2371 (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
68477355 2372 ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
d323f8fb 2373 mark_block_used(ctx, blk);
95a7f15f
TT
2374 p->num_blocks++;
2375 }
1e3472c5
TT
2376 if (blockcnt >= 0)
2377 p->last_block = blockcnt;
95a7f15f 2378 p->previous_block = blk;
50e1e10f 2379mark_dir:
1e3472c5 2380 if (p->is_dir && (blockcnt >= 0)) {
4dbe79bc 2381 while (++p->last_db_block < blockcnt) {
6dc64392
VAH
2382 pctx->errcode = ext2fs_add_dir_block2(fs->dblist,
2383 p->ino, 0,
2384 p->last_db_block);
4dbe79bc
TT
2385 if (pctx->errcode) {
2386 pctx->blk = 0;
2387 pctx->num = p->last_db_block;
2388 goto failed_add_dir_block;
2389 }
2390 }
6dc64392
VAH
2391 pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino,
2392 blk, blockcnt);
1b6bf175
TT
2393 if (pctx->errcode) {
2394 pctx->blk = blk;
2395 pctx->num = blockcnt;
4dbe79bc 2396 failed_add_dir_block:
1b6bf175 2397 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
08b21301
TT
2398 /* Should never get here */
2399 ctx->flags |= E2F_FLAG_ABORT;
2400 return BLOCK_ABORT;
3839e657 2401 }
3839e657 2402 }
50e1e10f 2403 return ret_code;
3839e657
TT
2404}
2405
53ef44c4 2406static int process_bad_block(ext2_filsys fs,
6dc64392 2407 blk64_t *block_nr,
9d1bd3de 2408 e2_blkcnt_t blockcnt,
6dc64392 2409 blk64_t ref_block EXT2FS_ATTR((unused)),
54434927 2410 int ref_offset EXT2FS_ATTR((unused)),
54dc7ca2 2411 void *priv_data)
3839e657
TT
2412{
2413 struct process_block_struct *p;
6dc64392
VAH
2414 blk64_t blk = *block_nr;
2415 blk64_t first_block;
54434927 2416 dgrp_t i;
21c84b71 2417 struct problem_context *pctx;
1b6bf175 2418 e2fsck_t ctx;
21c84b71 2419
1917875f
TT
2420 /*
2421 * Note: This function processes blocks for the bad blocks
2422 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
2423 */
2424
3839e657
TT
2425 if (!blk)
2426 return 0;
efc6f628 2427
54dc7ca2 2428 p = (struct process_block_struct *) priv_data;
1b6bf175 2429 ctx = p->ctx;
21c84b71 2430 pctx = p->pctx;
efc6f628 2431
f8188fff 2432 pctx->ino = EXT2_BAD_INO;
21c84b71
TT
2433 pctx->blk = blk;
2434 pctx->blkcount = blockcnt;
3839e657
TT
2435
2436 if ((blk < fs->super->s_first_data_block) ||
4efbac6f 2437 (blk >= ext2fs_blocks_count(fs->super))) {
1b6bf175 2438 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
3839e657
TT
2439 *block_nr = 0;
2440 return BLOCK_CHANGED;
21c84b71 2441 } else
3839e657 2442 return 0;
3839e657
TT
2443 }
2444
2445 if (blockcnt < 0) {
c5d2f50d 2446 if (ext2fs_test_block_bitmap2(p->fs_meta_blocks, blk)) {
000ba404
TT
2447 p->bbcheck = 1;
2448 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
2449 *block_nr = 0;
2450 return BLOCK_CHANGED;
2451 }
c5d2f50d 2452 } else if (ext2fs_test_block_bitmap2(ctx->block_found_map,
000ba404
TT
2453 blk)) {
2454 p->bbcheck = 1;
efc6f628 2455 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
000ba404
TT
2456 pctx)) {
2457 *block_nr = 0;
2458 return BLOCK_CHANGED;
2459 }
a02ce9df 2460 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
2461 return BLOCK_ABORT;
2462 } else
1b6bf175 2463 mark_block_used(ctx, blk);
3839e657
TT
2464 return 0;
2465 }
efc6f628 2466#if 0
50e1e10f 2467 printf ("DEBUG: Marking %u as bad.\n", blk);
3839e657 2468#endif
1b6bf175 2469 ctx->fs_badblocks_count++;
3839e657
TT
2470 /*
2471 * If the block is not used, then mark it as used and return.
2472 * If it is already marked as found, this must mean that
2473 * there's an overlap between the filesystem table blocks
2474 * (bitmaps and inode table) and the bad block list.
2475 */
c5d2f50d
VAH
2476 if (!ext2fs_test_block_bitmap2(ctx->block_found_map, blk)) {
2477 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
3839e657
TT
2478 return 0;
2479 }
f3db3566
TT
2480 /*
2481 * Try to find the where the filesystem block was used...
2482 */
2483 first_block = fs->super->s_first_data_block;
efc6f628 2484
f3db3566 2485 for (i = 0; i < fs->group_desc_count; i++ ) {
21c84b71 2486 pctx->group = i;
1b6bf175 2487 pctx->blk = blk;
8039c480
TT
2488 if (!ext2fs_bg_has_super(fs, i))
2489 goto skip_super;
f3db3566
TT
2490 if (blk == first_block) {
2491 if (i == 0) {
1b6bf175
TT
2492 if (fix_problem(ctx,
2493 PR_1_BAD_PRIMARY_SUPERBLOCK,
2494 pctx)) {
2495 *block_nr = 0;
50e1e10f 2496 return BLOCK_CHANGED;
1b6bf175 2497 }
50e1e10f 2498 return 0;
f3db3566 2499 }
1b6bf175 2500 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
f3db3566
TT
2501 return 0;
2502 }
2503 if ((blk > first_block) &&
2504 (blk <= first_block + fs->desc_blocks)) {
2505 if (i == 0) {
1b6bf175
TT
2506 pctx->blk = *block_nr;
2507 if (fix_problem(ctx,
2508 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
2509 *block_nr = 0;
50e1e10f 2510 return BLOCK_CHANGED;
1b6bf175 2511 }
50e1e10f 2512 return 0;
f3db3566 2513 }
1b6bf175 2514 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
f3db3566 2515 return 0;
3839e657 2516 }
8039c480 2517 skip_super:
d7cca6b0 2518 if (blk == ext2fs_block_bitmap_loc(fs, i)) {
1b6bf175
TT
2519 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
2520 ctx->invalid_block_bitmap_flag[i]++;
2521 ctx->invalid_bitmaps++;
21c84b71 2522 }
f3db3566
TT
2523 return 0;
2524 }
d7cca6b0 2525 if (blk == ext2fs_inode_bitmap_loc(fs, i)) {
1b6bf175
TT
2526 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
2527 ctx->invalid_inode_bitmap_flag[i]++;
2528 ctx->invalid_bitmaps++;
21c84b71 2529 }
f3db3566
TT
2530 return 0;
2531 }
d7cca6b0
VAH
2532 if ((blk >= ext2fs_inode_table_loc(fs, i)) &&
2533 (blk < (ext2fs_inode_table_loc(fs, i) +
f3db3566 2534 fs->inode_blocks_per_group))) {
21c84b71
TT
2535 /*
2536 * If there are bad blocks in the inode table,
2537 * the inode scan code will try to do
2538 * something reasonable automatically.
2539 */
f3db3566
TT
2540 return 0;
2541 }
8039c480 2542 first_block += fs->super->s_blocks_per_group;
f3db3566
TT
2543 }
2544 /*
2545 * If we've gotten to this point, then the only
2546 * possibility is that the bad block inode meta data
2547 * is using a bad block.
2548 */
2549 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
000ba404
TT
2550 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
2551 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
2552 p->bbcheck = 1;
2553 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
2554 *block_nr = 0;
2555 return BLOCK_CHANGED;
2556 }
a02ce9df 2557 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301 2558 return BLOCK_ABORT;
f3db3566 2559 return 0;
3839e657 2560 }
1b6bf175
TT
2561
2562 pctx->group = -1;
2563
2564 /* Warn user that the block wasn't claimed */
2565 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
2566
f3db3566 2567 return 0;
3839e657
TT
2568}
2569
3971bfe8 2570static void new_table_block(e2fsck_t ctx, blk64_t first_block, dgrp_t group,
c5d2f50d 2571 const char *name, int num, blk64_t *new_block)
3839e657 2572{
1b6bf175 2573 ext2_filsys fs = ctx->fs;
617446e4 2574 dgrp_t last_grp;
c5d2f50d
VAH
2575 blk64_t old_block = *new_block;
2576 blk64_t last_block;
3971bfe8
TT
2577 dgrp_t flexbg;
2578 unsigned flexbg_size;
2579 int i, is_flexbg;
3839e657 2580 char *buf;
1b6bf175
TT
2581 struct problem_context pctx;
2582
2583 clear_problem_context(&pctx);
2584
2585 pctx.group = group;
2586 pctx.blk = old_block;
2587 pctx.str = name;
2588
617446e4
TT
2589 /*
2590 * For flex_bg filesystems, first try to allocate the metadata
2591 * within the flex_bg, and if that fails then try finding the
2592 * space anywhere in the filesystem.
2593 */
2594 is_flexbg = EXT2_HAS_INCOMPAT_FEATURE(fs->super,
2595 EXT4_FEATURE_INCOMPAT_FLEX_BG);
2596 if (is_flexbg) {
2597 flexbg_size = 1 << fs->super->s_log_groups_per_flex;
2598 flexbg = group / flexbg_size;
b49f78fe
TT
2599 first_block = ext2fs_group_first_block2(fs,
2600 flexbg_size * flexbg);
617446e4
TT
2601 last_grp = group | (flexbg_size - 1);
2602 if (last_grp > fs->group_desc_count)
2603 last_grp = fs->group_desc_count;
b49f78fe 2604 last_block = ext2fs_group_last_block2(fs, last_grp);
617446e4 2605 } else
b49f78fe 2606 last_block = ext2fs_group_last_block2(fs, group);
c5d2f50d
VAH
2607 pctx.errcode = ext2fs_get_free_blocks2(fs, first_block, last_block,
2608 num, ctx->block_found_map,
2609 new_block);
617446e4 2610 if (is_flexbg && (pctx.errcode == EXT2_ET_BLOCK_ALLOC_FAIL))
c5d2f50d 2611 pctx.errcode = ext2fs_get_free_blocks2(fs,
617446e4 2612 fs->super->s_first_data_block,
4efbac6f 2613 ext2fs_blocks_count(fs->super),
617446e4 2614 num, ctx->block_found_map, new_block);
1b6bf175
TT
2615 if (pctx.errcode) {
2616 pctx.num = num;
2617 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
3839e657 2618 ext2fs_unmark_valid(fs);
617446e4 2619 ctx->flags |= E2F_FLAG_ABORT;
3839e657
TT
2620 return;
2621 }
c4e3d3f3 2622 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
08b21301 2623 if (pctx.errcode) {
1b6bf175 2624 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
3839e657 2625 ext2fs_unmark_valid(fs);
617446e4 2626 ctx->flags |= E2F_FLAG_ABORT;
3839e657
TT
2627 return;
2628 }
2629 ext2fs_mark_super_dirty(fs);
299d7424 2630 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
1b6bf175
TT
2631 pctx.blk2 = *new_block;
2632 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
2633 PR_1_RELOC_TO), &pctx);
2634 pctx.blk2 = 0;
3839e657 2635 for (i = 0; i < num; i++) {
1b6bf175 2636 pctx.blk = i;
c5d2f50d 2637 ext2fs_mark_block_bitmap2(ctx->block_found_map, (*new_block)+i);
f3db3566 2638 if (old_block) {
24a117ab 2639 pctx.errcode = io_channel_read_blk64(fs->io,
1b6bf175
TT
2640 old_block + i, 1, buf);
2641 if (pctx.errcode)
2642 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
f3db3566
TT
2643 } else
2644 memset(buf, 0, fs->blocksize);
2645
1b6bf175 2646 pctx.blk = (*new_block) + i;
24a117ab 2647 pctx.errcode = io_channel_write_blk64(fs->io, pctx.blk,
3839e657 2648 1, buf);
1b6bf175
TT
2649 if (pctx.errcode)
2650 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
3839e657 2651 }
c4e3d3f3 2652 ext2fs_free_mem(&buf);
3839e657
TT
2653}
2654
2655/*
f3db3566
TT
2656 * This routine gets called at the end of pass 1 if bad blocks are
2657 * detected in the superblock, group descriptors, inode_bitmaps, or
2658 * block bitmaps. At this point, all of the blocks have been mapped
2659 * out, so we can try to allocate new block(s) to replace the bad
2660 * blocks.
3839e657 2661 */
1b6bf175 2662static void handle_fs_bad_blocks(e2fsck_t ctx)
3839e657 2663{
1b6bf175 2664 ext2_filsys fs = ctx->fs;
54434927 2665 dgrp_t i;
c5d2f50d
VAH
2666 blk64_t first_block;
2667 blk64_t new_blk;
3839e657
TT
2668
2669 for (i = 0; i < fs->group_desc_count; i++) {
b49f78fe 2670 first_block = ext2fs_group_first_block2(fs, i);
abf23439 2671
1b6bf175 2672 if (ctx->invalid_block_bitmap_flag[i]) {
c5d2f50d 2673 new_blk = ext2fs_block_bitmap_loc(fs, i);
0c4a0726 2674 new_table_block(ctx, first_block, i, _("block bitmap"),
c5d2f50d
VAH
2675 1, &new_blk);
2676 ext2fs_block_bitmap_loc_set(fs, i, new_blk);
3839e657 2677 }
1b6bf175 2678 if (ctx->invalid_inode_bitmap_flag[i]) {
c5d2f50d 2679 new_blk = ext2fs_inode_bitmap_loc(fs, i);
0c4a0726 2680 new_table_block(ctx, first_block, i, _("inode bitmap"),
c5d2f50d
VAH
2681 1, &new_blk);
2682 ext2fs_inode_bitmap_loc_set(fs, i, new_blk);
3839e657 2683 }
1b6bf175 2684 if (ctx->invalid_inode_table_flag[i]) {
c5d2f50d 2685 new_blk = ext2fs_inode_table_loc(fs, i);
0c4a0726 2686 new_table_block(ctx, first_block, i, _("inode table"),
efc6f628 2687 fs->inode_blocks_per_group,
c5d2f50d
VAH
2688 &new_blk);
2689 ext2fs_inode_table_loc_set(fs, i, new_blk);
08b21301 2690 ctx->flags |= E2F_FLAG_RESTART;
3839e657 2691 }
3839e657 2692 }
1b6bf175 2693 ctx->invalid_bitmaps = 0;
3839e657
TT
2694}
2695
2696/*
2697 * This routine marks all blocks which are used by the superblock,
2698 * group descriptors, inode bitmaps, and block bitmaps.
2699 */
1b6bf175 2700static void mark_table_blocks(e2fsck_t ctx)
3839e657 2701{
1b6bf175 2702 ext2_filsys fs = ctx->fs;
6dc64392 2703 blk64_t b;
54434927 2704 dgrp_t i;
68477355 2705 unsigned int j;
21c84b71 2706 struct problem_context pctx;
efc6f628 2707
21c84b71 2708 clear_problem_context(&pctx);
efc6f628 2709
3839e657 2710 for (i = 0; i < fs->group_desc_count; i++) {
21c84b71 2711 pctx.group = i;
da2e97f7 2712
ef344e13
TT
2713 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
2714
21c84b71
TT
2715 /*
2716 * Mark the blocks used for the inode table
2717 */
d7cca6b0
VAH
2718 if (ext2fs_inode_table_loc(fs, i)) {
2719 for (j = 0, b = ext2fs_inode_table_loc(fs, i);
21c84b71
TT
2720 j < fs->inode_blocks_per_group;
2721 j++, b++) {
c5d2f50d 2722 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
21c84b71
TT
2723 b)) {
2724 pctx.blk = b;
9a7fe4bd
TT
2725 if (!ctx->invalid_inode_table_flag[i] &&
2726 fix_problem(ctx,
21c84b71 2727 PR_1_ITABLE_CONFLICT, &pctx)) {
1b6bf175
TT
2728 ctx->invalid_inode_table_flag[i]++;
2729 ctx->invalid_bitmaps++;
21c84b71
TT
2730 }
2731 } else {
c5d2f50d 2732 ext2fs_mark_block_bitmap2(ctx->block_found_map,
21c84b71 2733 b);
21c84b71
TT
2734 }
2735 }
2736 }
efc6f628 2737
3839e657 2738 /*
efc6f628 2739 * Mark block used for the block bitmap
3839e657 2740 */
d7cca6b0 2741 if (ext2fs_block_bitmap_loc(fs, i)) {
c5d2f50d 2742 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
d7cca6b0
VAH
2743 ext2fs_block_bitmap_loc(fs, i))) {
2744 pctx.blk = ext2fs_block_bitmap_loc(fs, i);
1b6bf175
TT
2745 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
2746 ctx->invalid_block_bitmap_flag[i]++;
2747 ctx->invalid_bitmaps++;
f3db3566 2748 }
50e1e10f 2749 } else {
c5d2f50d 2750 ext2fs_mark_block_bitmap2(ctx->block_found_map,
d7cca6b0 2751 ext2fs_block_bitmap_loc(fs, i));
50e1e10f 2752 }
efc6f628 2753
f3db3566 2754 }
3839e657 2755 /*
efc6f628 2756 * Mark block used for the inode bitmap
3839e657 2757 */
d7cca6b0 2758 if (ext2fs_inode_bitmap_loc(fs, i)) {
c5d2f50d 2759 if (ext2fs_test_block_bitmap2(ctx->block_found_map,
d7cca6b0
VAH
2760 ext2fs_inode_bitmap_loc(fs, i))) {
2761 pctx.blk = ext2fs_inode_bitmap_loc(fs, i);
1b6bf175
TT
2762 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
2763 ctx->invalid_inode_bitmap_flag[i]++;
2764 ctx->invalid_bitmaps++;
efc6f628 2765 }
50e1e10f 2766 } else {
c5d2f50d 2767 ext2fs_mark_block_bitmap2(ctx->block_found_map,
d7cca6b0 2768 ext2fs_inode_bitmap_loc(fs, i));
50e1e10f 2769 }
f3db3566 2770 }
3839e657
TT
2771 }
2772}
efc6f628 2773
3839e657 2774/*
e72a9ba3 2775 * Thes subroutines short circuits ext2fs_get_blocks and
3839e657
TT
2776 * ext2fs_check_directory; we use them since we already have the inode
2777 * structure, so there's no point in letting the ext2fs library read
2778 * the inode again.
2779 */
86c627ec
TT
2780static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
2781 blk_t *blocks)
3839e657 2782{
54dc7ca2 2783 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3839e657 2784 int i;
efc6f628 2785
71d521c6 2786 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
521e3685
TT
2787 return EXT2_ET_CALLBACK_NOTHANDLED;
2788
2789 for (i=0; i < EXT2_N_BLOCKS; i++)
1b6bf175 2790 blocks[i] = ctx->stashed_inode->i_block[i];
521e3685 2791 return 0;
3839e657
TT
2792}
2793
86c627ec 2794static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
e72a9ba3 2795 struct ext2_inode *inode)
1e3472c5 2796{
54dc7ca2 2797 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2798
71d521c6 2799 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1e3472c5 2800 return EXT2_ET_CALLBACK_NOTHANDLED;
1b6bf175 2801 *inode = *ctx->stashed_inode;
1e3472c5
TT
2802 return 0;
2803}
2804
86c627ec 2805static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
1e3472c5
TT
2806 struct ext2_inode *inode)
2807{
54dc7ca2 2808 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2809
27431595
TT
2810 if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
2811 (inode != ctx->stashed_inode))
1b6bf175 2812 *ctx->stashed_inode = *inode;
1e3472c5
TT
2813 return EXT2_ET_CALLBACK_NOTHANDLED;
2814}
2815
86c627ec 2816static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
3839e657 2817{
54dc7ca2 2818 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175 2819
71d521c6 2820 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
1b6bf175
TT
2821 return EXT2_ET_CALLBACK_NOTHANDLED;
2822
2823 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
291c9049 2824 return EXT2_ET_NO_DIRECTORY;
1b6bf175 2825 return 0;
3839e657 2826}
e72a9ba3 2827
16bd349e
TT
2828static errcode_t e2fsck_get_alloc_block(ext2_filsys fs, blk64_t goal,
2829 blk64_t *ret)
2830{
2831 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2832 errcode_t retval;
c5d2f50d 2833 blk64_t new_block;
16bd349e
TT
2834
2835 if (ctx->block_found_map) {
28843200
TT
2836 retval = ext2fs_new_block2(fs, goal, ctx->block_found_map,
2837 &new_block);
16bd349e
TT
2838 if (retval)
2839 return retval;
8a2cbe2c 2840 if (fs->block_map) {
2d07b3ad 2841 ext2fs_mark_block_bitmap2(fs->block_map, new_block);
8a2cbe2c
TT
2842 ext2fs_mark_bb_dirty(fs);
2843 }
16bd349e
TT
2844 } else {
2845 if (!fs->block_map) {
2846 retval = ext2fs_read_block_bitmap(fs);
2847 if (retval)
2848 return retval;
2849 }
2850
28843200 2851 retval = ext2fs_new_block2(fs, goal, 0, &new_block);
16bd349e
TT
2852 if (retval)
2853 return retval;
2854 }
efc6f628 2855
16bd349e
TT
2856 *ret = new_block;
2857 return (0);
2858}
2859
2860static void e2fsck_block_alloc_stats(ext2_filsys fs, blk64_t blk, int inuse)
2861{
2862 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2863
2864 if (ctx->block_found_map) {
2865 if (inuse > 0)
28843200 2866 ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
16bd349e 2867 else
28843200 2868 ext2fs_unmark_block_bitmap2(ctx->block_found_map, blk);
16bd349e
TT
2869 }
2870}
2871
2d2abcc6 2872void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int use_shortcuts)
e72a9ba3
TT
2873{
2874 ext2_filsys fs = ctx->fs;
2875
2d2abcc6 2876 if (use_shortcuts) {
e72a9ba3
TT
2877 fs->get_blocks = pass1_get_blocks;
2878 fs->check_directory = pass1_check_directory;
2879 fs->read_inode = pass1_read_inode;
2880 fs->write_inode = pass1_write_inode;
2881 ctx->stashed_ino = 0;
16bd349e
TT
2882 ext2fs_set_alloc_block_callback(fs, e2fsck_get_alloc_block,
2883 0);
2884 ext2fs_set_block_alloc_stats_callback(fs,
2885 e2fsck_block_alloc_stats,
2886 0);
e72a9ba3
TT
2887 } else {
2888 fs->get_blocks = 0;
2889 fs->check_directory = 0;
2890 fs->read_inode = 0;
2891 fs->write_inode = 0;
2892 }
2893}