]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blame - e2fsck/pass1.c
ChangeLog, debugfs.c:
[thirdparty/e2fsprogs.git] / e2fsck / pass1.c
CommitLineData
3839e657
TT
1/*
2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
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%
3839e657
TT
10 *
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)
22 * - A bitmap of which inodes have bad fields. (inode_bad_map)
21c84b71 23 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
3839e657
TT
24 * - A bitmap of which blocks are in use. (block_found_map)
25 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
26 * - The data blocks of the directory inodes. (dir_map)
27 *
28 * Pass 1 is designed to stash away enough information so that the
29 * other passes should not need to read in the inode information
30 * during the normal course of a filesystem check. (Althogh if an
31 * inconsistency is detected, other passes may need to read in an
32 * inode to fix it.)
33 *
34 * Note that pass 1B will be invoked if there are any duplicate blocks
35 * found.
36 */
37
38#include <time.h>
50e1e10f
TT
39#ifdef HAVE_ERRNO_H
40#include <errno.h>
41#endif
3839e657 42
3839e657 43#include "e2fsck.h"
21c84b71 44#include "problem.h"
3839e657 45
50e1e10f
TT
46#ifdef NO_INLINE_FUNCS
47#define _INLINE_
48#else
49#define _INLINE_ inline
50#endif
51
3839e657 52static int process_block(ext2_filsys fs, blk_t *blocknr,
9d1bd3de 53 e2_blkcnt_t blockcnt, blk_t ref_blk,
54dc7ca2 54 int ref_offset, void *priv_data);
3839e657 55static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
9d1bd3de 56 e2_blkcnt_t blockcnt, blk_t ref_blk,
54dc7ca2 57 int ref_offset, void *priv_data);
1b6bf175 58static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657 59 char *block_buf);
1b6bf175
TT
60static void mark_table_blocks(e2fsck_t ctx);
61static void alloc_bad_map(e2fsck_t ctx);
62static void alloc_bb_map(e2fsck_t ctx);
63static void handle_fs_bad_blocks(e2fsck_t ctx);
64static void process_inodes(e2fsck_t ctx, char *block_buf);
4c77fe50 65static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
f3db3566 66static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
54dc7ca2 67 dgrp_t group, void * priv_data);
21c84b71 68/* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3839e657
TT
69
70struct process_block_struct {
246501c6
TT
71 ino_t ino;
72 int is_dir:1, clear:1, suppress:1, fragmented:1;
73 blk_t num_blocks;
9d1bd3de 74 e2_blkcnt_t last_block;
246501c6
TT
75 int num_illegal_blocks;
76 blk_t previous_block;
f3db3566 77 struct ext2_inode *inode;
21c84b71 78 struct problem_context *pctx;
1b6bf175 79 e2fsck_t ctx;
3839e657
TT
80};
81
82struct process_inode_block {
83 ino_t ino;
84 struct ext2_inode inode;
85};
86
f8188fff
TT
87struct scan_callback_struct {
88 e2fsck_t ctx;
89 char *block_buf;
90};
91
3839e657
TT
92/*
93 * For the inodes to process list.
94 */
95static struct process_inode_block *inodes_to_process;
96static int process_inode_count;
3839e657 97
9d1bd3de 98static __u64 ext2_max_sizes[4];
246501c6 99
f3db3566
TT
100/*
101 * Free all memory allocated by pass1 in preparation for restarting
102 * things.
103 */
104static void unwind_pass1(ext2_filsys fs)
105{
08b21301
TT
106 ext2fs_free_mem((void **) &inodes_to_process);
107 inodes_to_process = 0;
f3db3566
TT
108}
109
7cf73dcd
TT
110/*
111 * Check to make sure a device inode is real. Returns 1 if the device
112 * checks out, 0 if not.
1dde43f0
TT
113 *
114 * Note: this routine is now also used to check FIFO's and Sockets,
115 * since they have the same requirement; the i_block fields should be
116 * zero.
7cf73dcd
TT
117 */
118int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
119{
120 int i;
121
7fdfabd3
TT
122 /*
123 * We should be able to do the test below all the time, but
124 * because the kernel doesn't forcibly clear the device
125 * inode's additional i_block fields, there are some rare
126 * occasions when a legitimate device inode will have non-zero
127 * additional i_block fields. So for now, we only complain
128 * when the immutable flag is set, which should never happen
129 * for devices. (And that's when the problem is caused, since
130 * you can't set or clear immutable flags for devices.) Once
131 * the kernel has been fixed we can change this...
132 */
133 if (inode->i_flags & EXT2_IMMUTABLE_FL) {
134 for (i=4; i < EXT2_N_BLOCKS; i++)
135 if (inode->i_block[i])
136 return 0;
137 }
7cf73dcd
TT
138 return 1;
139}
140
08b21301 141void e2fsck_pass1(e2fsck_t ctx)
3839e657 142{
9d1bd3de
TT
143 int i;
144 __u64 max_sizes;
1b6bf175 145 ext2_filsys fs = ctx->fs;
3839e657
TT
146 ino_t ino;
147 struct ext2_inode inode;
148 ext2_inode_scan scan;
149 char *block_buf;
8bf191e8 150#ifdef RESOURCE_TRACK
3839e657 151 struct resource_track rtrack;
8bf191e8 152#endif
1e3472c5 153 unsigned char frag, fsize;
21c84b71 154 struct problem_context pctx;
f8188fff 155 struct scan_callback_struct scan_struct;
874b4d26 156 struct ext2fs_sb *sb;
3839e657 157
8bf191e8 158#ifdef RESOURCE_TRACK
3839e657 159 init_resource_track(&rtrack);
8bf191e8 160#endif
1b6bf175
TT
161 clear_problem_context(&pctx);
162
163 if (!(ctx->options & E2F_OPT_PREEN))
164 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3839e657
TT
165
166#ifdef MTRACE
167 mtrace_print("Pass 1");
168#endif
169
9d1bd3de
TT
170#define EXT2_BPP(bits) (1UL << ((bits) - 2))
171
172 for (i=0; i < 4; i++) {
173 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(10+i);
174 max_sizes = max_sizes + EXT2_BPP(10+i) * EXT2_BPP(10+i);
175 max_sizes = (max_sizes +
176 (__u64) EXT2_BPP(10+i) * EXT2_BPP(10+i) *
177 EXT2_BPP(10+i));
178 max_sizes = (max_sizes * (1UL << (10+i))) - 1;
179 ext2_max_sizes[i] = max_sizes;
180 }
181#undef EXT2_BPP
182
3839e657
TT
183 /*
184 * Allocate bitmaps structures
185 */
1b6bf175
TT
186 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "in-use inode map",
187 &ctx->inode_used_map);
188 if (pctx.errcode) {
189 pctx.num = 1;
190 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
191 ctx->flags |= E2F_FLAG_ABORT;
192 return;
3839e657 193 }
1b6bf175
TT
194 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "directory inode map",
195 &ctx->inode_dir_map);
196 if (pctx.errcode) {
197 pctx.num = 2;
198 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
199 ctx->flags |= E2F_FLAG_ABORT;
200 return;
3839e657 201 }
1b6bf175
TT
202 pctx.errcode = ext2fs_allocate_block_bitmap(fs, "in-use block map",
203 &ctx->block_found_map);
204 if (pctx.errcode) {
205 pctx.num = 1;
206 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
08b21301
TT
207 ctx->flags |= E2F_FLAG_ABORT;
208 return;
3839e657 209 }
1b6bf175
TT
210 pctx.errcode = ext2fs_allocate_block_bitmap(fs, "illegal block map",
211 &ctx->block_illegal_map);
212 if (pctx.errcode) {
213 pctx.num = 2;
214 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
08b21301
TT
215 ctx->flags |= E2F_FLAG_ABORT;
216 return;
50e1e10f 217 }
1b6bf175
TT
218 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
219 &ctx->inode_link_info);
220 if (pctx.errcode) {
221 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
08b21301
TT
222 ctx->flags |= E2F_FLAG_ABORT;
223 return;
21c84b71 224 }
54dc7ca2
TT
225 inodes_to_process = (struct process_inode_block *)
226 e2fsck_allocate_memory(ctx,
227 (ctx->process_inode_size *
228 sizeof(struct process_inode_block)),
229 "array of inodes to process");
3839e657
TT
230 process_inode_count = 0;
231
1b6bf175
TT
232 pctx.errcode = ext2fs_init_dblist(fs, 0);
233 if (pctx.errcode) {
234 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
08b21301
TT
235 ctx->flags |= E2F_FLAG_ABORT;
236 return;
21c84b71 237 }
3839e657 238
1b6bf175 239 mark_table_blocks(ctx);
54dc7ca2
TT
240 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
241 "block interate buffer");
3839e657
TT
242 fs->get_blocks = pass1_get_blocks;
243 fs->check_directory = pass1_check_directory;
1e3472c5
TT
244 fs->read_inode = pass1_read_inode;
245 fs->write_inode = pass1_write_inode;
3839e657 246 ehandler_operation("doing inode scan");
1b6bf175
TT
247 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
248 &scan);
249 if (pctx.errcode) {
250 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
08b21301
TT
251 ctx->flags |= E2F_FLAG_ABORT;
252 return;
3839e657 253 }
21c84b71 254 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
1b6bf175
TT
255 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
256 if (pctx.errcode) {
257 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
08b21301
TT
258 ctx->flags |= E2F_FLAG_ABORT;
259 return;
3839e657 260 }
1b6bf175 261 ctx->stashed_inode = &inode;
f8188fff
TT
262 scan_struct.ctx = ctx;
263 scan_struct.block_buf = block_buf;
264 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
265 if (ctx->progress)
a02ce9df
TT
266 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
267 return;
3839e657 268 while (ino) {
21c84b71
TT
269 pctx.ino = ino;
270 pctx.inode = &inode;
1b6bf175
TT
271 ctx->stashed_ino = ino;
272 if (inode.i_links_count) {
273 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
274 ino, inode.i_links_count);
275 if (pctx.errcode) {
276 pctx.num = inode.i_links_count;
277 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
08b21301
TT
278 ctx->flags |= E2F_FLAG_ABORT;
279 return;
1b6bf175
TT
280 }
281 }
3839e657
TT
282 if (ino == EXT2_BAD_INO) {
283 struct process_block_struct pb;
284
285 pb.ino = EXT2_BAD_INO;
286 pb.num_blocks = pb.last_block = 0;
f3db3566 287 pb.num_illegal_blocks = 0;
21c84b71 288 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
74becf3c 289 pb.fragmented = 0;
f3db3566 290 pb.inode = &inode;
21c84b71 291 pb.pctx = &pctx;
1b6bf175
TT
292 pb.ctx = ctx;
293 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
294 block_buf, process_bad_block, &pb);
295 if (pctx.errcode) {
296 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
08b21301
TT
297 ctx->flags |= E2F_FLAG_ABORT;
298 return;
1b6bf175
TT
299 }
300 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
21c84b71 301 clear_problem_context(&pctx);
3839e657
TT
302 goto next;
303 }
304 if (ino == EXT2_ROOT_INO) {
305 /*
306 * Make sure the root inode is a directory; if
307 * not, offer to clear it. It will be
308 * regnerated in pass #3.
309 */
50e1e10f 310 if (!LINUX_S_ISDIR(inode.i_mode)) {
1b6bf175 311 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3839e657
TT
312 inode.i_dtime = time(0);
313 inode.i_links_count = 0;
1b6bf175 314 ext2fs_icount_store(ctx->inode_link_info,
21c84b71 315 ino, 0);
08b21301 316 e2fsck_write_inode(ctx, ino, &inode,
f3db3566 317 "pass1");
21c84b71 318 }
3839e657
TT
319 }
320 /*
321 * If dtime is set, offer to clear it. mke2fs
322 * version 0.2b created filesystems with the
323 * dtime field set for the root and lost+found
324 * directories. We won't worry about
325 * /lost+found, since that can be regenerated
326 * easily. But we will fix the root directory
327 * as a special case.
328 */
329 if (inode.i_dtime && inode.i_links_count) {
1b6bf175 330 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3839e657 331 inode.i_dtime = 0;
08b21301 332 e2fsck_write_inode(ctx, ino, &inode,
f3db3566 333 "pass1");
21c84b71 334 }
3839e657
TT
335 }
336 }
7f88b043
TT
337 if ((ino != EXT2_ROOT_INO) &&
338 (ino < EXT2_FIRST_INODE(fs->super))) {
1b6bf175 339 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
9d1bd3de
TT
340 if (((ino == EXT2_BOOT_LOADER_INO) &&
341 LINUX_S_ISDIR(inode.i_mode)) ||
342 ((ino != EXT2_BOOT_LOADER_INO) &&
343 (inode.i_mode != 0))) {
1b6bf175 344 if (fix_problem(ctx,
21c84b71 345 PR_1_RESERVED_BAD_MODE, &pctx)) {
50e1e10f 346 inode.i_mode = 0;
08b21301 347 e2fsck_write_inode(ctx, ino, &inode,
50e1e10f 348 "pass1");
21c84b71 349 }
50e1e10f 350 }
1b6bf175 351 check_blocks(ctx, &pctx, block_buf);
3839e657
TT
352 goto next;
353 }
354 /*
355 * This code assumes that deleted inodes have
356 * i_links_count set to 0.
357 */
358 if (!inode.i_links_count) {
359 if (!inode.i_dtime && inode.i_mode) {
1b6bf175 360 if (fix_problem(ctx,
21c84b71 361 PR_1_ZERO_DTIME, &pctx)) {
3839e657 362 inode.i_dtime = time(0);
08b21301 363 e2fsck_write_inode(ctx, ino, &inode,
f3db3566 364 "pass1");
21c84b71 365 }
3839e657
TT
366 }
367 goto next;
368 }
369 /*
1e3472c5 370 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3839e657 371 * deleted files. Oops.
1e3472c5
TT
372 *
373 * Since all new ext2 implementations get this right,
374 * we now assume that the case of non-zero
375 * i_links_count and non-zero dtime means that we
376 * should keep the file, not delete it.
3839e657 377 *
3839e657
TT
378 */
379 if (inode.i_dtime) {
1b6bf175 380 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
1e3472c5 381 inode.i_dtime = 0;
08b21301 382 e2fsck_write_inode(ctx, ino, &inode, "pass1");
21c84b71 383 }
3839e657
TT
384 }
385
1b6bf175 386 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
1e3472c5
TT
387 switch (fs->super->s_creator_os) {
388 case EXT2_OS_LINUX:
389 frag = inode.osd2.linux2.l_i_frag;
390 fsize = inode.osd2.linux2.l_i_fsize;
391 break;
392 case EXT2_OS_HURD:
393 frag = inode.osd2.hurd2.h_i_frag;
394 fsize = inode.osd2.hurd2.h_i_fsize;
395 break;
396 case EXT2_OS_MASIX:
397 frag = inode.osd2.masix2.m_i_frag;
398 fsize = inode.osd2.masix2.m_i_fsize;
399 break;
400 default:
401 frag = fsize = 0;
402 }
403
404 if (inode.i_faddr || frag || fsize
246501c6
TT
405 || inode.i_file_acl ||
406 (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl)) {
1b6bf175
TT
407 if (!ctx->inode_bad_map)
408 alloc_bad_map(ctx);
409 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3839e657
TT
410 }
411
50e1e10f 412 if (LINUX_S_ISDIR(inode.i_mode)) {
1b6bf175 413 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
08b21301 414 e2fsck_add_dir_info(ctx, ino, 0);
1b6bf175 415 ctx->fs_directory_count++;
50e1e10f 416 } else if (LINUX_S_ISREG (inode.i_mode))
1b6bf175 417 ctx->fs_regular_count++;
7cf73dcd
TT
418 else if (LINUX_S_ISCHR (inode.i_mode) &&
419 e2fsck_pass1_check_device_inode(&inode))
1b6bf175 420 ctx->fs_chardev_count++;
7cf73dcd
TT
421 else if (LINUX_S_ISBLK (inode.i_mode) &&
422 e2fsck_pass1_check_device_inode(&inode))
1b6bf175 423 ctx->fs_blockdev_count++;
50e1e10f 424 else if (LINUX_S_ISLNK (inode.i_mode)) {
1b6bf175 425 ctx->fs_symlinks_count++;
21c84b71 426 if (!inode.i_blocks) {
1b6bf175 427 ctx->fs_fast_symlinks_count++;
21c84b71
TT
428 goto next;
429 }
3839e657 430 }
1dde43f0
TT
431 else if (LINUX_S_ISFIFO (inode.i_mode) &&
432 e2fsck_pass1_check_device_inode(&inode))
1b6bf175 433 ctx->fs_fifo_count++;
1dde43f0
TT
434 else if ((LINUX_S_ISSOCK (inode.i_mode)) &&
435 e2fsck_pass1_check_device_inode(&inode))
1b6bf175 436 ctx->fs_sockets_count++;
3839e657 437 else {
1b6bf175
TT
438 if (!ctx->inode_bad_map)
439 alloc_bad_map(ctx);
440 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3839e657 441 }
50e1e10f 442 if (inode.i_block[EXT2_IND_BLOCK])
1b6bf175 443 ctx->fs_ind_count++;
50e1e10f 444 if (inode.i_block[EXT2_DIND_BLOCK])
1b6bf175 445 ctx->fs_dind_count++;
50e1e10f 446 if (inode.i_block[EXT2_TIND_BLOCK])
1b6bf175 447 ctx->fs_tind_count++;
3839e657
TT
448 if (inode.i_block[EXT2_IND_BLOCK] ||
449 inode.i_block[EXT2_DIND_BLOCK] ||
450 inode.i_block[EXT2_TIND_BLOCK]) {
451 inodes_to_process[process_inode_count].ino = ino;
452 inodes_to_process[process_inode_count].inode = inode;
453 process_inode_count++;
f3db3566 454 } else
1b6bf175 455 check_blocks(ctx, &pctx, block_buf);
3839e657 456
a02ce9df 457 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
458 return;
459
460 if (process_inode_count >= ctx->process_inode_size) {
1b6bf175 461 process_inodes(ctx, block_buf);
08b21301 462
a02ce9df 463 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
464 return;
465 }
3839e657 466 next:
1b6bf175 467 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
2df1f6aa
TT
468 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
469 return;
1b6bf175
TT
470 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
471 if (!ctx->inode_bb_map)
472 alloc_bb_map(ctx);
473 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
474 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
21c84b71
TT
475 goto next;
476 }
1b6bf175
TT
477 if (pctx.errcode) {
478 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
08b21301
TT
479 ctx->flags |= E2F_FLAG_ABORT;
480 return;
3839e657
TT
481 }
482 }
1b6bf175 483 process_inodes(ctx, block_buf);
3839e657
TT
484 ext2fs_close_inode_scan(scan);
485 ehandler_operation(0);
486
1b6bf175
TT
487 if (ctx->invalid_bitmaps)
488 handle_fs_bad_blocks(ctx);
f3db3566 489
08b21301 490 if (ctx->flags & E2F_FLAG_RESTART) {
f3db3566
TT
491 unwind_pass1(fs);
492 goto endit;
493 }
494
1b6bf175
TT
495 if (ctx->block_dup_map) {
496 if (ctx->options & E2F_OPT_PREEN) {
497 clear_problem_context(&pctx);
498 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3839e657 499 }
08b21301 500 e2fsck_pass1_dupblocks(ctx, block_buf);
3839e657 501 }
08b21301 502 ext2fs_free_mem((void **) &inodes_to_process);
f3db3566 503endit:
1e3472c5
TT
504 fs->get_blocks = 0;
505 fs->check_directory = 0;
506 fs->read_inode = 0;
507 fs->write_inode = 0;
508
08b21301 509 ext2fs_free_mem((void **) &block_buf);
1b6bf175
TT
510 ext2fs_free_block_bitmap(ctx->block_illegal_map);
511 ctx->block_illegal_map = 0;
21c84b71 512
874b4d26 513 sb = (struct ext2fs_sb *) fs->super;
246501c6 514 if (ctx->large_files &&
874b4d26 515 !(sb->s_feature_ro_compat &
246501c6
TT
516 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
517 if (fix_problem(ctx, PR_1_FEATURE_LARGE_FILES, &pctx)) {
874b4d26 518 sb->s_feature_ro_compat |=
246501c6
TT
519 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
520 ext2fs_mark_super_dirty(fs);
521 }
522 } else if (!ctx->large_files &&
874b4d26 523 (sb->s_feature_ro_compat &
246501c6
TT
524 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
525 if (fs->flags & EXT2_FLAG_RW) {
874b4d26 526 sb->s_feature_ro_compat &=
246501c6
TT
527 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
528 ext2fs_mark_super_dirty(fs);
529 }
530 }
531
8bf191e8 532#ifdef RESOURCE_TRACK
1b6bf175
TT
533 if (ctx->options & E2F_OPT_TIME2)
534 print_resource_track("Pass 1", &rtrack);
8bf191e8 535#endif
3839e657
TT
536}
537
f3db3566
TT
538/*
539 * When the inode_scan routines call this callback at the end of the
540 * glock group, call process_inodes.
541 */
542static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
54dc7ca2 543 dgrp_t group, void * priv_data)
f3db3566 544{
54dc7ca2 545 struct scan_callback_struct *scan_struct;
f8188fff
TT
546 e2fsck_t ctx;
547
54dc7ca2 548 scan_struct = (struct scan_callback_struct *) priv_data;
f8188fff
TT
549 ctx = scan_struct->ctx;
550
54dc7ca2 551 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
f8188fff
TT
552
553 if (ctx->progress)
a02ce9df
TT
554 if ((ctx->progress)(ctx, 1, group+1,
555 ctx->fs->group_desc_count))
556 return EXT2_ET_CANCEL_REQUESTED;
f8188fff 557
f3db3566
TT
558 return 0;
559}
560
3839e657
TT
561/*
562 * Process the inodes in the "inodes to process" list.
563 */
1b6bf175 564static void process_inodes(e2fsck_t ctx, char *block_buf)
3839e657
TT
565{
566 int i;
567 struct ext2_inode *old_stashed_inode;
21c84b71 568 ino_t old_stashed_ino;
3839e657
TT
569 const char *old_operation;
570 char buf[80];
21c84b71
TT
571 struct problem_context pctx;
572
3839e657 573#if 0
f3db3566 574 printf("begin process_inodes: ");
3839e657
TT
575#endif
576 old_operation = ehandler_operation(0);
1b6bf175
TT
577 old_stashed_inode = ctx->stashed_inode;
578 old_stashed_ino = ctx->stashed_ino;
3839e657
TT
579 qsort(inodes_to_process, process_inode_count,
580 sizeof(struct process_inode_block), process_inode_cmp);
21c84b71 581 clear_problem_context(&pctx);
3839e657 582 for (i=0; i < process_inode_count; i++) {
1b6bf175
TT
583 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
584 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
21c84b71 585
3839e657 586#if 0
21c84b71 587 printf("%u ", pctx.ino);
3839e657 588#endif
21c84b71 589 sprintf(buf, "reading indirect blocks of inode %lu", pctx.ino);
3839e657 590 ehandler_operation(buf);
1b6bf175 591 check_blocks(ctx, &pctx, block_buf);
a02ce9df 592 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2df1f6aa 593 break;
3839e657 594 }
1b6bf175
TT
595 ctx->stashed_inode = old_stashed_inode;
596 ctx->stashed_ino = old_stashed_ino;
3839e657
TT
597 process_inode_count = 0;
598#if 0
f3db3566 599 printf("end process inodes\n");
3839e657
TT
600#endif
601 ehandler_operation(old_operation);
602}
603
4c77fe50 604static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
3839e657
TT
605{
606 const struct process_inode_block *ib_a =
607 (const struct process_inode_block *) a;
608 const struct process_inode_block *ib_b =
609 (const struct process_inode_block *) b;
610
611 return (ib_a->inode.i_block[EXT2_IND_BLOCK] -
612 ib_b->inode.i_block[EXT2_IND_BLOCK]);
613}
614
3839e657
TT
615/*
616 * This procedure will allocate the inode bad map table
617 */
1b6bf175 618static void alloc_bad_map(e2fsck_t ctx)
3839e657 619{
1b6bf175
TT
620 struct problem_context pctx;
621
622 clear_problem_context(&pctx);
3839e657 623
1b6bf175
TT
624 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, "bad inode map",
625 &ctx->inode_bad_map);
626 if (pctx.errcode) {
627 pctx.num = 3;
628 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
629 /* Should never get here */
630 ctx->flags |= E2F_FLAG_ABORT;
631 return;
3839e657
TT
632 }
633}
634
21c84b71
TT
635/*
636 * This procedure will allocate the inode "bb" (badblock) map table
637 */
1b6bf175 638static void alloc_bb_map(e2fsck_t ctx)
21c84b71 639{
1b6bf175 640 struct problem_context pctx;
21c84b71 641
1b6bf175
TT
642 clear_problem_context(&pctx);
643 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
644 "inode in bad block map",
645 &ctx->inode_bb_map);
646 if (pctx.errcode) {
647 pctx.num = 4;
648 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
08b21301
TT
649 /* Should never get here */
650 ctx->flags |= E2F_FLAG_ABORT;
651 return;
21c84b71
TT
652 }
653}
654
3839e657
TT
655/*
656 * Marks a block as in use, setting the dup_map if it's been set
657 * already. Called by process_block and process_bad_block.
50e1e10f
TT
658 *
659 * WARNING: Assumes checks have already been done to make sure block
660 * is valid. This is true in both process_block and process_bad_block.
3839e657 661 */
1b6bf175 662static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
3839e657 663{
1b6bf175
TT
664 struct problem_context pctx;
665
666 clear_problem_context(&pctx);
3839e657 667
1b6bf175
TT
668 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
669 if (!ctx->block_dup_map) {
670 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
671 "multiply claimed block map",
672 &ctx->block_dup_map);
673 if (pctx.errcode) {
674 pctx.num = 3;
675 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
676 &pctx);
08b21301
TT
677 /* Should never get here */
678 ctx->flags |= E2F_FLAG_ABORT;
679 return;
3839e657
TT
680 }
681 }
1b6bf175 682 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3839e657 683 } else {
1b6bf175 684 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3839e657
TT
685 }
686}
687
688/*
689 * This subroutine is called on each inode to account for all of the
690 * blocks used by that inode.
691 */
1b6bf175 692static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3839e657
TT
693 char *block_buf)
694{
1b6bf175 695 ext2_filsys fs = ctx->fs;
3839e657 696 struct process_block_struct pb;
21c84b71
TT
697 ino_t ino = pctx->ino;
698 struct ext2_inode *inode = pctx->inode;
246501c6
TT
699 int bad_size = 0;
700 __u64 size;
701 struct ext2fs_sb *sb;
3839e657 702
21c84b71 703 if (!ext2fs_inode_has_valid_blocks(pctx->inode))
3839e657
TT
704 return;
705
706 pb.ino = ino;
707 pb.num_blocks = pb.last_block = 0;
f3db3566 708 pb.num_illegal_blocks = 0;
21c84b71 709 pb.suppress = 0; pb.clear = 0;
74becf3c
TT
710 pb.fragmented = 0;
711 pb.previous_block = 0;
21c84b71 712 pb.is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
f3db3566 713 pb.inode = inode;
21c84b71 714 pb.pctx = pctx;
1b6bf175
TT
715 pb.ctx = ctx;
716 pctx->ino = ino;
717 pctx->errcode = ext2fs_block_iterate2(fs, ino,
21c84b71
TT
718 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
719 block_buf, process_block, &pb);
a02ce9df 720 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301 721 return;
1b6bf175
TT
722 end_problem_latch(ctx, PR_LATCH_BLOCK);
723 if (pctx->errcode)
724 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
3839e657 725
74becf3c 726 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
1b6bf175 727 ctx->fs_fragmented++;
74becf3c 728
f3db3566 729 if (pb.clear) {
08b21301 730 e2fsck_read_inode(ctx, ino, inode, "check_blocks");
f3db3566 731 inode->i_links_count = 0;
1b6bf175 732 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
f3db3566 733 inode->i_dtime = time(0);
08b21301 734 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
1b6bf175
TT
735 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
736 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
f3db3566
TT
737 /*
738 * The inode was probably partially accounted for
739 * before processing was aborted, so we need to
740 * restart the pass 1 scan.
741 */
08b21301 742 ctx->flags |= E2F_FLAG_RESTART;
f3db3566
TT
743 return;
744 }
745
3839e657
TT
746 pb.num_blocks *= (fs->blocksize / 512);
747#if 0
246501c6 748 printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
3839e657
TT
749 ino, inode->i_size, pb.last_block, inode->i_blocks,
750 pb.num_blocks);
751#endif
752 if (!pb.num_blocks && pb.is_dir) {
1b6bf175 753 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
3839e657 754 inode->i_links_count = 0;
1b6bf175 755 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
3839e657 756 inode->i_dtime = time(0);
08b21301 757 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
1b6bf175
TT
758 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
759 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
760 ctx->fs_directory_count--;
50e1e10f 761 pb.is_dir = 0;
21c84b71 762 }
3839e657 763 }
246501c6
TT
764 if (pb.is_dir) {
765 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
766 if ((nblock > (pb.last_block + 1)) ||
767 ((inode->i_size & (fs->blocksize-1)) != 0))
768 bad_size = 1;
769 else if (nblock < (pb.last_block + 1)) {
770 sb = (struct ext2fs_sb *) fs->super;
771 if (((pb.last_block + 1) - nblock) >
772 sb->s_prealloc_dir_blocks)
9d1bd3de 773 bad_size = 2;
246501c6
TT
774 }
775 } else {
776 size = inode->i_size + ((__u64) inode->i_size_high << 32);
777 if ((size < pb.last_block * fs->blocksize))
9d1bd3de 778 bad_size = 3;
246501c6 779 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
9d1bd3de 780 bad_size = 4;
246501c6
TT
781 }
782 if (bad_size) {
21c84b71 783 pctx->num = (pb.last_block+1) * fs->blocksize;
1b6bf175 784 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
21c84b71 785 inode->i_size = pctx->num;
246501c6
TT
786 if (!pb.is_dir)
787 inode->i_size_high = pctx->num >> 32;
08b21301 788 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
21c84b71
TT
789 }
790 pctx->num = 0;
3839e657 791 }
246501c6
TT
792 if (!pb.is_dir && inode->i_size_high)
793 ctx->large_files++;
3839e657 794 if (pb.num_blocks != inode->i_blocks) {
21c84b71 795 pctx->num = pb.num_blocks;
1b6bf175 796 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
3839e657 797 inode->i_blocks = pb.num_blocks;
08b21301 798 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
21c84b71
TT
799 }
800 pctx->num = 0;
3839e657 801 }
50e1e10f
TT
802}
803
21c84b71 804#if 0
50e1e10f
TT
805/*
806 * Helper function called by process block when an illegal block is
807 * found. It returns a description about why the block is illegal
808 */
809static char *describe_illegal_block(ext2_filsys fs, blk_t block)
810{
811 blk_t super;
812 int i;
813 static char problem[80];
814
815 super = fs->super->s_first_data_block;
816 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
817 if (block < super) {
818 sprintf(problem, "< FIRSTBLOCK (%u)", super);
819 return(problem);
820 } else if (block >= fs->super->s_blocks_count) {
821 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
822 return(problem);
823 }
824 for (i = 0; i < fs->group_desc_count; i++) {
825 if (block == super) {
826 sprintf(problem, "is the superblock in group %d", i);
827 break;
828 }
829 if (block > super &&
830 block <= (super + fs->desc_blocks)) {
831 sprintf(problem, "is in the group descriptors "
832 "of group %d", i);
833 break;
834 }
835 if (block == fs->group_desc[i].bg_block_bitmap) {
836 sprintf(problem, "is the block bitmap of group %d", i);
837 break;
838 }
839 if (block == fs->group_desc[i].bg_inode_bitmap) {
840 sprintf(problem, "is the inode bitmap of group %d", i);
841 break;
842 }
843 if (block >= fs->group_desc[i].bg_inode_table &&
844 (block < fs->group_desc[i].bg_inode_table
845 + fs->inode_blocks_per_group)) {
846 sprintf(problem, "is in the inode table of group %d",
847 i);
848 break;
849 }
850 super += fs->super->s_blocks_per_group;
851 }
852 return(problem);
853}
21c84b71 854#endif
3839e657
TT
855
856/*
857 * This is a helper function for check_blocks().
858 */
859int process_block(ext2_filsys fs,
860 blk_t *block_nr,
9d1bd3de 861 e2_blkcnt_t blockcnt,
21c84b71
TT
862 blk_t ref_block,
863 int ref_offset,
54dc7ca2 864 void *priv_data)
3839e657
TT
865{
866 struct process_block_struct *p;
21c84b71 867 struct problem_context *pctx;
3839e657 868 blk_t blk = *block_nr;
50e1e10f 869 int ret_code = 0;
21c84b71 870 int problem = 0;
1b6bf175 871 e2fsck_t ctx;
3839e657 872
54dc7ca2 873 p = (struct process_block_struct *) priv_data;
21c84b71 874 pctx = p->pctx;
1b6bf175 875 ctx = p->ctx;
3839e657 876
50e1e10f
TT
877 if (blk == 0) {
878 if (p->is_dir == 0) {
1e3472c5
TT
879 /*
880 * Should never happen, since only directories
881 * get called with BLOCK_FLAG_HOLE
882 */
1b6bf175 883#if DEBUG_E2FSCK
50e1e10f 884 printf("process_block() called with blk == 0, "
5c576477
TT
885 "blockcnt=%d, inode %lu???\n",
886 blockcnt, p->ino);
1b6bf175 887#endif
50e1e10f
TT
888 return 0;
889 }
890 if (blockcnt < 0)
891 return 0;
892 if (blockcnt * fs->blocksize < p->inode->i_size) {
21c84b71
TT
893#if 0
894 printf("Missing block (#%d) in directory inode %lu!\n",
895 blockcnt, p->ino);
896#endif
50e1e10f
TT
897 goto mark_dir;
898 }
899 return 0;
900 }
901
3839e657 902#if 0
50e1e10f 903 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
3839e657 904 blockcnt);
50e1e10f 905#endif
3839e657 906
74becf3c
TT
907 /*
908 * Simplistic fragmentation check. We merely require that the
909 * file be contiguous. (Which can never be true for really
910 * big files that are greater than a block group.)
911 */
912 if (p->previous_block) {
913 if (p->previous_block+1 != blk)
914 p->fragmented = 1;
915 }
916 p->previous_block = blk;
917
50e1e10f 918 if (blk < fs->super->s_first_data_block ||
21c84b71
TT
919 blk >= fs->super->s_blocks_count)
920 problem = PR_1_ILLEGAL_BLOCK_NUM;
521e3685
TT
921#if 0
922 else
923 if (ext2fs_test_block_bitmap(block_illegal_map, blk))
924 problem = PR_1_BLOCK_OVERLAPS_METADATA;
925#endif
21c84b71
TT
926
927 if (problem) {
f3db3566 928 p->num_illegal_blocks++;
21c84b71 929 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
1b6bf175 930 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
f3db3566
TT
931 p->clear = 1;
932 return BLOCK_ABORT;
933 }
f8188fff 934 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
f3db3566 935 p->suppress = 1;
1b6bf175
TT
936 set_latch_flags(PR_LATCH_BLOCK,
937 PRL_SUPPRESS, 0);
f3db3566
TT
938 }
939 }
21c84b71
TT
940 pctx->blk = blk;
941 pctx->blkcount = blockcnt;
1b6bf175 942 if (fix_problem(ctx, problem, pctx)) {
50e1e10f
TT
943 blk = *block_nr = 0;
944 ret_code = BLOCK_CHANGED;
945 goto mark_dir;
21c84b71 946 } else
3839e657 947 return 0;
21c84b71
TT
948 pctx->blk = 0;
949 pctx->blkcount = -1;
3839e657
TT
950 }
951
1b6bf175 952 mark_block_used(ctx, blk);
50e1e10f 953 p->num_blocks++;
1e3472c5
TT
954 if (blockcnt >= 0)
955 p->last_block = blockcnt;
50e1e10f 956mark_dir:
1e3472c5 957 if (p->is_dir && (blockcnt >= 0)) {
1b6bf175
TT
958 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
959 blk, blockcnt);
960 if (pctx->errcode) {
961 pctx->blk = blk;
962 pctx->num = blockcnt;
963 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
08b21301
TT
964 /* Should never get here */
965 ctx->flags |= E2F_FLAG_ABORT;
966 return BLOCK_ABORT;
3839e657 967 }
3839e657 968 }
50e1e10f 969 return ret_code;
3839e657
TT
970}
971
1b6bf175 972static void bad_block_indirect(e2fsck_t ctx, blk_t blk)
f3db3566 973{
1b6bf175 974 struct problem_context pctx;
f3db3566 975
1b6bf175
TT
976 clear_problem_context(&pctx);
977 /*
978 * Prompt to see if we should continue or not.
979 */
980 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, &pctx))
08b21301 981 ctx->flags |= E2F_FLAG_ABORT;
50e1e10f
TT
982}
983
3839e657
TT
984int process_bad_block(ext2_filsys fs,
985 blk_t *block_nr,
9d1bd3de 986 e2_blkcnt_t blockcnt,
21c84b71
TT
987 blk_t ref_block,
988 int ref_offset,
54dc7ca2 989 void *priv_data)
3839e657
TT
990{
991 struct process_block_struct *p;
3839e657 992 blk_t blk = *block_nr;
f3db3566
TT
993 int first_block;
994 int i;
21c84b71 995 struct problem_context *pctx;
1b6bf175 996 e2fsck_t ctx;
21c84b71 997
3839e657
TT
998 if (!blk)
999 return 0;
21c84b71 1000
54dc7ca2 1001 p = (struct process_block_struct *) priv_data;
1b6bf175 1002 ctx = p->ctx;
21c84b71
TT
1003 pctx = p->pctx;
1004
f8188fff 1005 pctx->ino = EXT2_BAD_INO;
21c84b71
TT
1006 pctx->blk = blk;
1007 pctx->blkcount = blockcnt;
3839e657
TT
1008
1009 if ((blk < fs->super->s_first_data_block) ||
1010 (blk >= fs->super->s_blocks_count)) {
1b6bf175 1011 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
3839e657
TT
1012 *block_nr = 0;
1013 return BLOCK_CHANGED;
21c84b71 1014 } else
3839e657 1015 return 0;
3839e657
TT
1016 }
1017
1018 if (blockcnt < 0) {
08b21301 1019 if (ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1b6bf175 1020 bad_block_indirect(ctx, blk);
a02ce9df 1021 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301
TT
1022 return BLOCK_ABORT;
1023 } else
1b6bf175 1024 mark_block_used(ctx, blk);
3839e657
TT
1025 return 0;
1026 }
1027#if 0
50e1e10f 1028 printf ("DEBUG: Marking %u as bad.\n", blk);
3839e657 1029#endif
1b6bf175 1030 ctx->fs_badblocks_count++;
3839e657
TT
1031 /*
1032 * If the block is not used, then mark it as used and return.
1033 * If it is already marked as found, this must mean that
1034 * there's an overlap between the filesystem table blocks
1035 * (bitmaps and inode table) and the bad block list.
1036 */
1b6bf175
TT
1037 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1038 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
3839e657
TT
1039 return 0;
1040 }
f3db3566
TT
1041 /*
1042 * Try to find the where the filesystem block was used...
1043 */
1044 first_block = fs->super->s_first_data_block;
1045
1046 for (i = 0; i < fs->group_desc_count; i++ ) {
21c84b71 1047 pctx->group = i;
1b6bf175 1048 pctx->blk = blk;
8039c480
TT
1049 if (!ext2fs_bg_has_super(fs, i))
1050 goto skip_super;
f3db3566
TT
1051 if (blk == first_block) {
1052 if (i == 0) {
1b6bf175
TT
1053 if (fix_problem(ctx,
1054 PR_1_BAD_PRIMARY_SUPERBLOCK,
1055 pctx)) {
1056 *block_nr = 0;
50e1e10f 1057 return BLOCK_CHANGED;
1b6bf175 1058 }
50e1e10f 1059 return 0;
f3db3566 1060 }
1b6bf175 1061 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
f3db3566
TT
1062 return 0;
1063 }
1064 if ((blk > first_block) &&
1065 (blk <= first_block + fs->desc_blocks)) {
1066 if (i == 0) {
1b6bf175
TT
1067 pctx->blk = *block_nr;
1068 if (fix_problem(ctx,
1069 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
1070 *block_nr = 0;
50e1e10f 1071 return BLOCK_CHANGED;
1b6bf175 1072 }
50e1e10f 1073 return 0;
f3db3566 1074 }
1b6bf175 1075 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
f3db3566 1076 return 0;
3839e657 1077 }
8039c480 1078 skip_super:
f3db3566 1079 if (blk == fs->group_desc[i].bg_block_bitmap) {
1b6bf175
TT
1080 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
1081 ctx->invalid_block_bitmap_flag[i]++;
1082 ctx->invalid_bitmaps++;
21c84b71 1083 }
f3db3566
TT
1084 return 0;
1085 }
1086 if (blk == fs->group_desc[i].bg_inode_bitmap) {
1b6bf175
TT
1087 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
1088 ctx->invalid_inode_bitmap_flag[i]++;
1089 ctx->invalid_bitmaps++;
21c84b71 1090 }
f3db3566
TT
1091 return 0;
1092 }
1093 if ((blk >= fs->group_desc[i].bg_inode_table) &&
1094 (blk < (fs->group_desc[i].bg_inode_table +
1095 fs->inode_blocks_per_group))) {
21c84b71
TT
1096 /*
1097 * If there are bad blocks in the inode table,
1098 * the inode scan code will try to do
1099 * something reasonable automatically.
1100 */
f3db3566
TT
1101 return 0;
1102 }
8039c480 1103 first_block += fs->super->s_blocks_per_group;
f3db3566
TT
1104 }
1105 /*
1106 * If we've gotten to this point, then the only
1107 * possibility is that the bad block inode meta data
1108 * is using a bad block.
1109 */
1110 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
1111 p->inode->i_block[EXT2_DIND_BLOCK]) {
1b6bf175 1112 bad_block_indirect(ctx, blk);
a02ce9df 1113 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
08b21301 1114 return BLOCK_ABORT;
f3db3566 1115 return 0;
3839e657 1116 }
1b6bf175
TT
1117
1118 pctx->group = -1;
1119
1120 /* Warn user that the block wasn't claimed */
1121 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
1122
f3db3566 1123 return 0;
3839e657
TT
1124}
1125
1b6bf175 1126static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
3839e657
TT
1127 const char *name, int num, blk_t *new_block)
1128{
1b6bf175 1129 ext2_filsys fs = ctx->fs;
3839e657
TT
1130 blk_t old_block = *new_block;
1131 int i;
1132 char *buf;
1b6bf175
TT
1133 struct problem_context pctx;
1134
1135 clear_problem_context(&pctx);
1136
1137 pctx.group = group;
1138 pctx.blk = old_block;
1139 pctx.str = name;
1140
1141 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
3839e657 1142 first_block + fs->super->s_blocks_per_group,
1b6bf175
TT
1143 num, ctx->block_found_map, new_block);
1144 if (pctx.errcode) {
1145 pctx.num = num;
1146 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
3839e657
TT
1147 ext2fs_unmark_valid(fs);
1148 return;
1149 }
08b21301
TT
1150 pctx.errcode = ext2fs_get_mem(fs->blocksize, (void **) &buf);
1151 if (pctx.errcode) {
1b6bf175 1152 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
3839e657
TT
1153 ext2fs_unmark_valid(fs);
1154 return;
1155 }
1156 ext2fs_mark_super_dirty(fs);
1b6bf175
TT
1157 pctx.blk2 = *new_block;
1158 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
1159 PR_1_RELOC_TO), &pctx);
1160 pctx.blk2 = 0;
3839e657 1161 for (i = 0; i < num; i++) {
1b6bf175
TT
1162 pctx.blk = i;
1163 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
f3db3566 1164 if (old_block) {
1b6bf175
TT
1165 pctx.errcode = io_channel_read_blk(fs->io,
1166 old_block + i, 1, buf);
1167 if (pctx.errcode)
1168 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
f3db3566
TT
1169 } else
1170 memset(buf, 0, fs->blocksize);
1171
1b6bf175
TT
1172 pctx.blk = (*new_block) + i;
1173 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
3839e657 1174 1, buf);
1b6bf175
TT
1175 if (pctx.errcode)
1176 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
3839e657 1177 }
08b21301 1178 ext2fs_free_mem((void **) &buf);
3839e657
TT
1179}
1180
1181/*
f3db3566
TT
1182 * This routine gets called at the end of pass 1 if bad blocks are
1183 * detected in the superblock, group descriptors, inode_bitmaps, or
1184 * block bitmaps. At this point, all of the blocks have been mapped
1185 * out, so we can try to allocate new block(s) to replace the bad
1186 * blocks.
3839e657 1187 */
1b6bf175 1188static void handle_fs_bad_blocks(e2fsck_t ctx)
3839e657 1189{
1b6bf175 1190 ext2_filsys fs = ctx->fs;
f3db3566
TT
1191 int i;
1192 int first_block = fs->super->s_first_data_block;
3839e657
TT
1193
1194 for (i = 0; i < fs->group_desc_count; i++) {
1b6bf175
TT
1195 if (ctx->invalid_block_bitmap_flag[i]) {
1196 new_table_block(ctx, first_block, i, "block bitmap",
1197 1, &fs->group_desc[i].bg_block_bitmap);
3839e657 1198 }
1b6bf175
TT
1199 if (ctx->invalid_inode_bitmap_flag[i]) {
1200 new_table_block(ctx, first_block, i, "inode bitmap",
1201 1, &fs->group_desc[i].bg_inode_bitmap);
3839e657 1202 }
1b6bf175
TT
1203 if (ctx->invalid_inode_table_flag[i]) {
1204 new_table_block(ctx, first_block, i, "inode table",
f3db3566 1205 fs->inode_blocks_per_group,
3839e657 1206 &fs->group_desc[i].bg_inode_table);
08b21301 1207 ctx->flags |= E2F_FLAG_RESTART;
3839e657 1208 }
3839e657
TT
1209 first_block += fs->super->s_blocks_per_group;
1210 }
1b6bf175 1211 ctx->invalid_bitmaps = 0;
3839e657
TT
1212}
1213
1214/*
1215 * This routine marks all blocks which are used by the superblock,
1216 * group descriptors, inode bitmaps, and block bitmaps.
1217 */
1b6bf175 1218static void mark_table_blocks(e2fsck_t ctx)
3839e657 1219{
1b6bf175 1220 ext2_filsys fs = ctx->fs;
f3db3566 1221 blk_t block, b;
3839e657 1222 int i,j;
21c84b71
TT
1223 struct problem_context pctx;
1224
1225 clear_problem_context(&pctx);
3839e657
TT
1226
1227 block = fs->super->s_first_data_block;
1228 for (i = 0; i < fs->group_desc_count; i++) {
21c84b71 1229 pctx.group = i;
da2e97f7
TT
1230
1231 if (ext2fs_bg_has_super(fs, i)) {
1232 /*
1233 * Mark this group's copy of the superblock
1234 */
1b6bf175
TT
1235 ext2fs_mark_block_bitmap(ctx->block_found_map, block);
1236 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1237 block);
da2e97f7
TT
1238
1239 /*
1240 * Mark this group's copy of the descriptors
1241 */
1242 for (j = 0; j < fs->desc_blocks; j++) {
1b6bf175 1243 ext2fs_mark_block_bitmap(ctx->block_found_map,
da2e97f7 1244 block + j + 1);
1b6bf175 1245 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
da2e97f7
TT
1246 block + j + 1);
1247 }
1248 }
1249
21c84b71
TT
1250 /*
1251 * Mark the blocks used for the inode table
1252 */
1253 if (fs->group_desc[i].bg_inode_table) {
1254 for (j = 0, b = fs->group_desc[i].bg_inode_table;
1255 j < fs->inode_blocks_per_group;
1256 j++, b++) {
1b6bf175 1257 if (ext2fs_test_block_bitmap(ctx->block_found_map,
21c84b71
TT
1258 b)) {
1259 pctx.blk = b;
1b6bf175 1260 if (fix_problem(ctx,
21c84b71 1261 PR_1_ITABLE_CONFLICT, &pctx)) {
1b6bf175
TT
1262 ctx->invalid_inode_table_flag[i]++;
1263 ctx->invalid_bitmaps++;
21c84b71
TT
1264 }
1265 } else {
1b6bf175 1266 ext2fs_mark_block_bitmap(ctx->block_found_map,
21c84b71 1267 b);
1b6bf175 1268 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
21c84b71
TT
1269 b);
1270 }
1271 }
1272 }
1273
3839e657
TT
1274 /*
1275 * Mark block used for the block bitmap
1276 */
f3db3566 1277 if (fs->group_desc[i].bg_block_bitmap) {
1b6bf175 1278 if (ext2fs_test_block_bitmap(ctx->block_found_map,
f3db3566 1279 fs->group_desc[i].bg_block_bitmap)) {
21c84b71 1280 pctx.blk = fs->group_desc[i].bg_block_bitmap;
1b6bf175
TT
1281 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
1282 ctx->invalid_block_bitmap_flag[i]++;
1283 ctx->invalid_bitmaps++;
f3db3566 1284 }
50e1e10f 1285 } else {
1b6bf175 1286 ext2fs_mark_block_bitmap(ctx->block_found_map,
f3db3566 1287 fs->group_desc[i].bg_block_bitmap);
1b6bf175 1288 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
50e1e10f
TT
1289 fs->group_desc[i].bg_block_bitmap);
1290 }
1291
f3db3566 1292 }
3839e657
TT
1293 /*
1294 * Mark block used for the inode bitmap
1295 */
f3db3566 1296 if (fs->group_desc[i].bg_inode_bitmap) {
1b6bf175 1297 if (ext2fs_test_block_bitmap(ctx->block_found_map,
f3db3566 1298 fs->group_desc[i].bg_inode_bitmap)) {
21c84b71 1299 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
1b6bf175
TT
1300 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
1301 ctx->invalid_inode_bitmap_flag[i]++;
1302 ctx->invalid_bitmaps++;
21c84b71 1303 }
50e1e10f 1304 } else {
1b6bf175 1305 ext2fs_mark_block_bitmap(ctx->block_found_map,
f3db3566 1306 fs->group_desc[i].bg_inode_bitmap);
1b6bf175 1307 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
50e1e10f
TT
1308 fs->group_desc[i].bg_inode_bitmap);
1309 }
f3db3566 1310 }
3839e657
TT
1311 block += fs->super->s_blocks_per_group;
1312 }
1313}
1314
1315/*
1316 * This subroutines short circuits ext2fs_get_blocks and
1317 * ext2fs_check_directory; we use them since we already have the inode
1318 * structure, so there's no point in letting the ext2fs library read
1319 * the inode again.
1320 */
1e3472c5 1321errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
3839e657 1322{
54dc7ca2 1323 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
3839e657
TT
1324 int i;
1325
1b6bf175 1326 if (ino != ctx->stashed_ino)
521e3685
TT
1327 return EXT2_ET_CALLBACK_NOTHANDLED;
1328
1329 for (i=0; i < EXT2_N_BLOCKS; i++)
1b6bf175 1330 blocks[i] = ctx->stashed_inode->i_block[i];
521e3685 1331 return 0;
3839e657
TT
1332}
1333
1e3472c5
TT
1334errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino, struct ext2_inode *inode)
1335{
54dc7ca2 1336 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175
TT
1337
1338 if (ino != ctx->stashed_ino)
1e3472c5 1339 return EXT2_ET_CALLBACK_NOTHANDLED;
1b6bf175 1340 *inode = *ctx->stashed_inode;
1e3472c5
TT
1341 return 0;
1342}
1343
1344errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
1345 struct ext2_inode *inode)
1346{
54dc7ca2 1347 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175
TT
1348
1349 if (ino == ctx->stashed_ino)
1350 *ctx->stashed_inode = *inode;
1e3472c5
TT
1351 return EXT2_ET_CALLBACK_NOTHANDLED;
1352}
1353
1354errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
3839e657 1355{
54dc7ca2 1356 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1b6bf175
TT
1357
1358 if (ino != ctx->stashed_ino)
1359 return EXT2_ET_CALLBACK_NOTHANDLED;
1360
1361 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
291c9049 1362 return EXT2_ET_NO_DIRECTORY;
1b6bf175 1363 return 0;
3839e657 1364}