Whamcloud - gitweb
Print an error if more than one of the -p/-a, -n or -y options
[tools/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
327         inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
328         ipg_max = inodes_per_block * (blocks_per_group - 4);
329         if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
330                 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
331         bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
332         if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
333                 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
334
335         ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
336                  sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
337         ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
338                  sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
339         ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
340                 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
341
342         clear_problem_context(&pctx);
343
344         /*
345          * Verify the super block constants...
346          */
347         check_super_value(ctx, "inodes_count", sb->s_inodes_count,
348                           MIN_CHECK, 1, 0);
349         check_super_value(ctx, "blocks_count", sb->s_blocks_count,
350                           MIN_CHECK, 1, 0);
351         check_super_value(ctx, "first_data_block", sb->s_first_data_block,
352                           MAX_CHECK, 0, sb->s_blocks_count);
353         check_super_value(ctx, "log_block_size", sb->s_log_block_size,
354                           MIN_CHECK | MAX_CHECK, 0,
355                           EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
356         check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
357                           MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
358         check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
359                           MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
360                           bpg_max);
361         check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
362                           MIN_CHECK | MAX_CHECK, 8, bpg_max);
363         check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
364                           MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
365         check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
366                           MAX_CHECK, 0, sb->s_blocks_count / 4);
367
368         if (!ctx->num_blocks) {
369                 pctx.errcode = e2fsck_get_device_size(ctx);
370                 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
371                         fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
372                         ctx->flags |= E2F_FLAG_ABORT;
373                         return;
374                 }
375                 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
376                     (ctx->num_blocks < sb->s_blocks_count)) {
377                         pctx.blk = sb->s_blocks_count;
378                         pctx.blk2 = ctx->num_blocks;
379                         if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
380                                 ctx->flags |= E2F_FLAG_ABORT;
381                                 return;
382                         }
383                 }
384         }
385
386         if (sb->s_log_block_size != sb->s_log_frag_size) {
387                 pctx.blk = EXT2_BLOCK_SIZE(sb);
388                 pctx.blk2 = EXT2_FRAG_SIZE(sb);
389                 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
390                 ctx->flags |= E2F_FLAG_ABORT;
391                 return;
392         }
393
394         should_be = sb->s_frags_per_group >>
395                 (sb->s_log_block_size - sb->s_log_frag_size);           
396         if (sb->s_blocks_per_group != should_be) {
397                 pctx.blk = sb->s_blocks_per_group;
398                 pctx.blk2 = should_be;
399                 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
400                 ctx->flags |= E2F_FLAG_ABORT;
401                 return;
402         }
403
404         should_be = (sb->s_log_block_size == 0) ? 1 : 0;
405         if (sb->s_first_data_block != should_be) {
406                 pctx.blk = sb->s_first_data_block;
407                 pctx.blk2 = should_be;
408                 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
409                 ctx->flags |= E2F_FLAG_ABORT;
410                 return;
411         }
412
413         should_be = sb->s_inodes_per_group * fs->group_desc_count;
414         if (sb->s_inodes_count != should_be) {
415                 pctx.ino = sb->s_inodes_count;
416                 pctx.ino2 = should_be;
417                 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
418                         sb->s_inodes_count = should_be;
419                         ext2fs_mark_super_dirty(fs);
420                 }
421         }
422
423         /*
424          * Verify the group descriptors....
425          */
426         first_block =  fs->super->s_first_data_block;
427         last_block = first_block + blocks_per_group;
428
429         for (i = 0; i < fs->group_desc_count; i++) {
430                 pctx.group = i;
431                 
432                 if (i == fs->group_desc_count - 1)
433                         last_block = fs->super->s_blocks_count;
434                 if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
435                     (fs->group_desc[i].bg_block_bitmap >= last_block)) {
436                         pctx.blk = fs->group_desc[i].bg_block_bitmap;
437                         if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
438                                 fs->group_desc[i].bg_block_bitmap = 0;
439                 }
440                 if (fs->group_desc[i].bg_block_bitmap == 0) {
441                         ctx->invalid_block_bitmap_flag[i]++;
442                         ctx->invalid_bitmaps++;
443                 }
444                 if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
445                     (fs->group_desc[i].bg_inode_bitmap >= last_block)) {
446                         pctx.blk = fs->group_desc[i].bg_inode_bitmap;
447                         if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
448                                 fs->group_desc[i].bg_inode_bitmap = 0;
449                 }
450                 if (fs->group_desc[i].bg_inode_bitmap == 0) {
451                         ctx->invalid_inode_bitmap_flag[i]++;
452                         ctx->invalid_bitmaps++;
453                 }
454                 if ((fs->group_desc[i].bg_inode_table < first_block) ||
455                     ((fs->group_desc[i].bg_inode_table +
456                       fs->inode_blocks_per_group - 1) >= last_block)) {
457                         pctx.blk = fs->group_desc[i].bg_inode_table;
458                         if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
459                                 fs->group_desc[i].bg_inode_table = 0;
460                 }
461                 if (fs->group_desc[i].bg_inode_table == 0) {
462                         ctx->invalid_inode_table_flag[i]++;
463                         ctx->invalid_bitmaps++;
464                 }
465                 first_block += fs->super->s_blocks_per_group;
466                 last_block += fs->super->s_blocks_per_group;
467         }
468         /*
469          * If we have invalid bitmaps, set the error state of the
470          * filesystem.
471          */
472         if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
473                 fs->super->s_state &= ~EXT2_VALID_FS;
474                 ext2fs_mark_super_dirty(fs);
475         }
476
477         clear_problem_context(&pctx);
478         
479 #ifndef EXT2_SKIP_UUID
480         /*
481          * If the UUID field isn't assigned, assign it.
482          */
483         if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
484                 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
485                         uuid_generate(sb->s_uuid);
486                         ext2fs_mark_super_dirty(fs);
487                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
488                 }
489         }
490 #endif
491         
492         /*
493          * For the Hurd, check to see if the filetype option is set,
494          * since it doesn't support it.
495          */
496         if (!(ctx->options & E2F_OPT_READONLY) &&
497             fs->super->s_creator_os == EXT2_OS_HURD &&
498             (fs->super->s_feature_incompat &
499              EXT2_FEATURE_INCOMPAT_FILETYPE)) {
500                 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
501                         fs->super->s_feature_incompat &=
502                                 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
503                         ext2fs_mark_super_dirty(fs);
504
505                 }
506         }
507
508         /*
509          * If we have any of the compatibility flags set, we need to have a
510          * revision 1 filesystem.  Most kernels will not check the flags on
511          * a rev 0 filesystem and we may have corruption issues because of
512          * the incompatible changes to the filesystem.
513          */
514         if (!(ctx->options & E2F_OPT_READONLY) &&
515             fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
516             (fs->super->s_feature_compat ||
517              fs->super->s_feature_ro_compat ||
518              fs->super->s_feature_incompat) &&
519             fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
520                 ext2fs_update_dynamic_rev(fs);
521                 ext2fs_mark_super_dirty(fs);
522         }
523
524         /*
525          * Clean up any orphan inodes, if present.
526          */
527         if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
528                 fs->super->s_state &= ~EXT2_VALID_FS;
529                 ext2fs_mark_super_dirty(fs);
530         }
531
532         /*
533          * Move the ext3 journal file, if necessary.
534          */
535         e2fsck_move_ext3_journal(ctx);
536         return;
537 }
538
539