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