]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blob - e2fsck/super.c
E2fsck now updates the global free block and
[thirdparty/e2fsprogs.git] / e2fsck / super.c
1 /*
2 * e2fsck.c - superblock checks
3 *
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%
10 */
11
12 #ifdef HAVE_ERRNO_H
13 #include <errno.h>
14 #endif
15
16 #ifndef EXT2_SKIP_UUID
17 #include "uuid/uuid.h"
18 #endif
19 #include "e2fsck.h"
20 #include "problem.h"
21
22 #define MIN_CHECK 1
23 #define MAX_CHECK 2
24
25 static void check_super_value(e2fsck_t ctx, const char *descr,
26 unsigned long value, int flags,
27 unsigned long min_val, unsigned long max_val)
28 {
29 struct problem_context pctx;
30
31 if (((flags & MIN_CHECK) && (value < min_val)) ||
32 ((flags & MAX_CHECK) && (value > max_val))) {
33 clear_problem_context(&pctx);
34 pctx.num = value;
35 pctx.str = descr;
36 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
37 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
38 }
39 }
40
41 /*
42 * This routine may get stubbed out in special compilations of the
43 * e2fsck code..
44 */
45 #ifndef EXT2_SPECIAL_DEVICE_SIZE
46 errcode_t e2fsck_get_device_size(e2fsck_t ctx)
47 {
48 return (ext2fs_get_device_size(ctx->filesystem_name,
49 EXT2_BLOCK_SIZE(ctx->fs->super),
50 &ctx->num_blocks));
51 }
52 #endif
53
54 /*
55 * helper function to release an inode
56 */
57 struct process_block_struct {
58 e2fsck_t ctx;
59 char *buf;
60 struct problem_context *pctx;
61 int truncating;
62 int truncate_offset;
63 blk_t truncate_block;
64 int truncated_blocks;
65 int abort;
66 errcode_t errcode;
67 };
68
69 static int release_inode_block(ext2_filsys fs,
70 blk_t *block_nr,
71 int blockcnt,
72 void *priv_data)
73 {
74 struct process_block_struct *pb;
75 e2fsck_t ctx;
76 struct problem_context *pctx;
77 blk_t blk = *block_nr;
78 int retval = 0;
79
80 pb = (struct process_block_struct *) priv_data;
81 ctx = pb->ctx;
82 pctx = pb->pctx;
83
84 pctx->blk = blk;
85 pctx->blkcount = blockcnt;
86
87 if (HOLE_BLKADDR(blk))
88 return 0;
89
90 if ((blk < fs->super->s_first_data_block) ||
91 (blk >= fs->super->s_blocks_count)) {
92 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
93 return_abort:
94 pb->abort = 1;
95 return BLOCK_ABORT;
96 }
97
98 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
99 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
100 goto return_abort;
101 }
102
103 /*
104 * If we are deleting an orphan, then we leave the fields alone.
105 * If we are truncating an orphan, then update the inode fields
106 * and clean up any partial block data.
107 */
108 if (pb->truncating) {
109 /*
110 * We only remove indirect blocks if they are
111 * completely empty.
112 */
113 if (blockcnt < 0) {
114 int i, limit;
115 blk_t *bp;
116
117 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
118 pb->buf);
119 if (pb->errcode)
120 goto return_abort;
121
122 limit = fs->blocksize >> 2;
123 for (i = 0, bp = (blk_t *) pb->buf;
124 i < limit; i++, bp++)
125 if (*bp)
126 return 0;
127 }
128 /*
129 * We don't remove direct blocks until we've reached
130 * the truncation block.
131 */
132 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
133 return 0;
134 /*
135 * If part of the last block needs truncating, we do
136 * it here.
137 */
138 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
139 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
140 pb->buf);
141 if (pb->errcode)
142 goto return_abort;
143 memset(pb->buf + pb->truncate_offset, 0,
144 fs->blocksize - pb->truncate_offset);
145 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
146 pb->buf);
147 if (pb->errcode)
148 goto return_abort;
149 }
150 pb->truncated_blocks++;
151 *block_nr = 0;
152 retval |= BLOCK_CHANGED;
153 }
154
155 ext2fs_block_alloc_stats(fs, blk, -1);
156 return retval;
157 }
158
159 /*
160 * This function releases an inode. Returns 1 if an inconsistency was
161 * found. If the inode has a link count, then it is being truncated and
162 * not deleted.
163 */
164 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
165 struct ext2_inode *inode, char *block_buf,
166 struct problem_context *pctx)
167 {
168 struct process_block_struct pb;
169 ext2_filsys fs = ctx->fs;
170 errcode_t retval;
171 __u32 count;
172
173 if (!ext2fs_inode_has_valid_blocks(inode))
174 return 0;
175
176 pb.buf = block_buf + 3 * ctx->fs->blocksize;
177 pb.ctx = ctx;
178 pb.abort = 0;
179 pb.errcode = 0;
180 pb.pctx = pctx;
181 if (inode->i_links_count) {
182 pb.truncating = 1;
183 pb.truncate_block = (blk_t)
184 ((((long long)inode->i_size_high << 32) +
185 inode->i_size + fs->blocksize - 1) /
186 fs->blocksize);
187 pb.truncate_offset = inode->i_size % fs->blocksize;
188 } else {
189 pb.truncating = 0;
190 pb.truncate_block = 0;
191 pb.truncate_offset = 0;
192 }
193 pb.truncated_blocks = 0;
194 retval = ext2fs_block_iterate(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
195 block_buf, release_inode_block, &pb);
196 if (retval) {
197 com_err("release_inode_blocks", retval,
198 _("while calling ext2fs_block_iterate for inode %d"),
199 ino);
200 return 1;
201 }
202 if (pb.abort)
203 return 1;
204
205 /* Refresh the inode since ext2fs_block_iterate may have changed it */
206 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
207
208 if (pb.truncated_blocks)
209 inode->i_blocks -= pb.truncated_blocks *
210 (fs->blocksize / 512);
211
212 if (inode->i_file_acl) {
213 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
214 block_buf, -1, &count);
215 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
216 retval = 0;
217 count = 1;
218 }
219 if (retval) {
220 com_err("release_inode_blocks", retval,
221 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
222 ino);
223 return 1;
224 }
225 if (count == 0)
226 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
227 inode->i_file_acl = 0;
228 }
229 return 0;
230 }
231
232 /*
233 * This function releases all of the orphan inodes. It returns 1 if
234 * it hit some error, and 0 on success.
235 */
236 static int release_orphan_inodes(e2fsck_t ctx)
237 {
238 ext2_filsys fs = ctx->fs;
239 ext2_ino_t ino, next_ino;
240 struct ext2_inode inode;
241 struct problem_context pctx;
242 char *block_buf;
243
244 if ((ino = fs->super->s_last_orphan) == 0)
245 return 0;
246
247 /*
248 * Win or lose, we won't be using the head of the orphan inode
249 * list again.
250 */
251 fs->super->s_last_orphan = 0;
252 ext2fs_mark_super_dirty(fs);
253
254 /*
255 * If the filesystem contains errors, don't run the orphan
256 * list, since the orphan list can't be trusted; and we're
257 * going to be running a full e2fsck run anyway...
258 */
259 if (fs->super->s_state & EXT2_ERROR_FS)
260 return 0;
261
262 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
263 (ino > fs->super->s_inodes_count)) {
264 clear_problem_context(&pctx);
265 pctx.ino = ino;
266 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
267 return 1;
268 }
269
270 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
271 "block iterate buffer");
272 e2fsck_read_bitmaps(ctx);
273
274 while (ino) {
275 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
276 clear_problem_context(&pctx);
277 pctx.ino = ino;
278 pctx.inode = &inode;
279 pctx.str = inode.i_links_count ? _("Truncating") :
280 _("Clearing");
281
282 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
283
284 next_ino = inode.i_dtime;
285 if (next_ino &&
286 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
287 (next_ino > fs->super->s_inodes_count))) {
288 pctx.ino = next_ino;
289 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
290 goto return_abort;
291 }
292
293 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
294 goto return_abort;
295
296 if (!inode.i_links_count) {
297 ext2fs_inode_alloc_stats2(fs, ino, -1,
298 LINUX_S_ISDIR(inode.i_mode));
299 inode.i_dtime = time(0);
300 } else {
301 inode.i_dtime = 0;
302 }
303 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
304 ino = next_ino;
305 }
306 ext2fs_free_mem((void **) &block_buf);
307 return 0;
308 return_abort:
309 ext2fs_free_mem((void **) &block_buf);
310 return 1;
311 }
312
313
314 void check_super_block(e2fsck_t ctx)
315 {
316 ext2_filsys fs = ctx->fs;
317 blk_t first_block, last_block;
318 struct ext2_super_block *sb = fs->super;
319 blk_t blocks_per_group = fs->super->s_blocks_per_group;
320 blk_t bpg_max;
321 int inodes_per_block;
322 int ipg_max;
323 dgrp_t i;
324 blk_t should_be;
325 struct problem_context pctx;
326 __u32 free_blocks = 0, free_inodes = 0;
327
328 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
329 ipg_max = inodes_per_block * (blocks_per_group - 4);
330 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
331 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
332 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
333 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
334 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
335
336 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
337 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
338 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
339 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
340 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
341 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
342
343 clear_problem_context(&pctx);
344
345 /*
346 * Verify the super block constants...
347 */
348 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
349 MIN_CHECK, 1, 0);
350 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
351 MIN_CHECK, 1, 0);
352 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
353 MAX_CHECK, 0, sb->s_blocks_count);
354 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
355 MIN_CHECK | MAX_CHECK, 0,
356 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
357 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
358 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
359 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
360 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
361 bpg_max);
362 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
363 MIN_CHECK | MAX_CHECK, 8, bpg_max);
364 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
365 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
366 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
367 MAX_CHECK, 0, sb->s_blocks_count / 4);
368
369 if (!ctx->num_blocks) {
370 pctx.errcode = e2fsck_get_device_size(ctx);
371 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
372 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
373 ctx->flags |= E2F_FLAG_ABORT;
374 return;
375 }
376 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
377 (ctx->num_blocks < sb->s_blocks_count)) {
378 pctx.blk = sb->s_blocks_count;
379 pctx.blk2 = ctx->num_blocks;
380 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
381 ctx->flags |= E2F_FLAG_ABORT;
382 return;
383 }
384 }
385 }
386
387 if (sb->s_log_block_size != sb->s_log_frag_size) {
388 pctx.blk = EXT2_BLOCK_SIZE(sb);
389 pctx.blk2 = EXT2_FRAG_SIZE(sb);
390 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
391 ctx->flags |= E2F_FLAG_ABORT;
392 return;
393 }
394
395 should_be = sb->s_frags_per_group >>
396 (sb->s_log_block_size - sb->s_log_frag_size);
397 if (sb->s_blocks_per_group != should_be) {
398 pctx.blk = sb->s_blocks_per_group;
399 pctx.blk2 = should_be;
400 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
401 ctx->flags |= E2F_FLAG_ABORT;
402 return;
403 }
404
405 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
406 if (sb->s_first_data_block != should_be) {
407 pctx.blk = sb->s_first_data_block;
408 pctx.blk2 = should_be;
409 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
410 ctx->flags |= E2F_FLAG_ABORT;
411 return;
412 }
413
414 should_be = sb->s_inodes_per_group * fs->group_desc_count;
415 if (sb->s_inodes_count != should_be) {
416 pctx.ino = sb->s_inodes_count;
417 pctx.ino2 = should_be;
418 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
419 sb->s_inodes_count = should_be;
420 ext2fs_mark_super_dirty(fs);
421 }
422 }
423
424 /*
425 * Verify the group descriptors....
426 */
427 first_block = fs->super->s_first_data_block;
428 last_block = first_block + blocks_per_group;
429
430 for (i = 0; i < fs->group_desc_count; i++) {
431 pctx.group = i;
432
433 if (i == fs->group_desc_count - 1)
434 last_block = fs->super->s_blocks_count;
435 if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
436 (fs->group_desc[i].bg_block_bitmap >= last_block)) {
437 pctx.blk = fs->group_desc[i].bg_block_bitmap;
438 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
439 fs->group_desc[i].bg_block_bitmap = 0;
440 }
441 if (fs->group_desc[i].bg_block_bitmap == 0) {
442 ctx->invalid_block_bitmap_flag[i]++;
443 ctx->invalid_bitmaps++;
444 }
445 if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
446 (fs->group_desc[i].bg_inode_bitmap >= last_block)) {
447 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
448 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
449 fs->group_desc[i].bg_inode_bitmap = 0;
450 }
451 if (fs->group_desc[i].bg_inode_bitmap == 0) {
452 ctx->invalid_inode_bitmap_flag[i]++;
453 ctx->invalid_bitmaps++;
454 }
455 if ((fs->group_desc[i].bg_inode_table < first_block) ||
456 ((fs->group_desc[i].bg_inode_table +
457 fs->inode_blocks_per_group - 1) >= last_block)) {
458 pctx.blk = fs->group_desc[i].bg_inode_table;
459 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
460 fs->group_desc[i].bg_inode_table = 0;
461 }
462 if (fs->group_desc[i].bg_inode_table == 0) {
463 ctx->invalid_inode_table_flag[i]++;
464 ctx->invalid_bitmaps++;
465 }
466 free_blocks += fs->group_desc[i].bg_free_blocks_count;
467 free_inodes += fs->group_desc[i].bg_free_inodes_count;
468 first_block += fs->super->s_blocks_per_group;
469 last_block += fs->super->s_blocks_per_group;
470 }
471 /*
472 * If we have invalid bitmaps, set the error state of the
473 * filesystem.
474 */
475 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
476 fs->super->s_state &= ~EXT2_VALID_FS;
477 ext2fs_mark_super_dirty(fs);
478 }
479
480 clear_problem_context(&pctx);
481
482 #ifndef EXT2_SKIP_UUID
483 /*
484 * If the UUID field isn't assigned, assign it.
485 */
486 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
487 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
488 uuid_generate(sb->s_uuid);
489 ext2fs_mark_super_dirty(fs);
490 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
491 }
492 }
493 #endif
494
495 /*
496 * Update the global counts from the block group counts. This
497 * is needed for an experimental patch which eliminates
498 * locking the entire filesystem when allocating blocks or
499 * inodes; if the filesystem is not unmounted cleanly, the
500 * global counts may not be accurate.
501 */
502 if (!(ctx->options & E2F_OPT_READONLY) &&
503 ((free_blocks != fs->super->s_free_blocks_count) ||
504 (free_inodes != fs->super->s_free_inodes_count))) {
505 fs->super->s_free_blocks_count = free_blocks;
506 fs->super->s_free_inodes_count = free_inodes;
507 ext2fs_mark_super_dirty(fs);
508 }
509
510 /*
511 * For the Hurd, check to see if the filetype option is set,
512 * since it doesn't support it.
513 */
514 if (!(ctx->options & E2F_OPT_READONLY) &&
515 fs->super->s_creator_os == EXT2_OS_HURD &&
516 (fs->super->s_feature_incompat &
517 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
518 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
519 fs->super->s_feature_incompat &=
520 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
521 ext2fs_mark_super_dirty(fs);
522
523 }
524 }
525
526 /*
527 * If we have any of the compatibility flags set, we need to have a
528 * revision 1 filesystem. Most kernels will not check the flags on
529 * a rev 0 filesystem and we may have corruption issues because of
530 * the incompatible changes to the filesystem.
531 */
532 if (!(ctx->options & E2F_OPT_READONLY) &&
533 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
534 (fs->super->s_feature_compat ||
535 fs->super->s_feature_ro_compat ||
536 fs->super->s_feature_incompat) &&
537 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
538 ext2fs_update_dynamic_rev(fs);
539 ext2fs_mark_super_dirty(fs);
540 }
541
542 /*
543 * Clean up any orphan inodes, if present.
544 */
545 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
546 fs->super->s_state &= ~EXT2_VALID_FS;
547 ext2fs_mark_super_dirty(fs);
548 }
549
550 /*
551 * Move the ext3 journal file, if necessary.
552 */
553 e2fsck_move_ext3_journal(ctx);
554 return;
555 }
556
557