Whamcloud - gitweb
ChangeLog, pass5.c, problem.c, problem.h:
[tools/e2fsprogs.git] / e2fsck / super.c
index 62038be..5f15cee 100644 (file)
@@ -9,22 +9,9 @@
  * %End-Header%
  */
 
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif
-#include <unistd.h>
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
 
 #ifndef EXT2_SKIP_UUID
 #include "uuid/uuid.h"
 
 static void check_super_value(e2fsck_t ctx, const char *descr,
                              unsigned long value, int flags,
-                             unsigned long min, unsigned long max)
+                             unsigned long min_val, unsigned long max_val)
 {
        struct          problem_context pctx;
 
-       if (((flags & MIN_CHECK) && (value < min)) ||
-           ((flags & MAX_CHECK) && (value > max))) {
+       if (((flags & MIN_CHECK) && (value < min_val)) ||
+           ((flags & MAX_CHECK) && (value > max_val))) {
                clear_problem_context(&pctx);
                pctx.num = value;
                pctx.str = descr;
@@ -70,9 +57,14 @@ void check_super_block(e2fsck_t ctx)
        blk_t   first_block, last_block;
        struct ext2fs_sb *s = (struct ext2fs_sb *) fs->super;
        blk_t   blocks_per_group = fs->super->s_blocks_per_group;
-       int     i;
+       int     inodes_per_block;
+       dgrp_t  i;
        blk_t   should_be;
        struct problem_context  pctx;
+       
+       inodes_per_block = (EXT2_INODE_SIZE(fs->super) + 
+                           EXT2_BLOCK_SIZE(fs->super) - 1) /
+                                   EXT2_BLOCK_SIZE(fs->super);
 
        ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
                 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
@@ -102,7 +94,8 @@ void check_super_block(e2fsck_t ctx)
        check_super_value(ctx, "blocks_per_group", s->s_blocks_per_group,
                          MIN_CHECK | MAX_CHECK, 1, 8 * EXT2_BLOCK_SIZE(s));
        check_super_value(ctx, "inodes_per_group", s->s_inodes_per_group,
-                         MIN_CHECK, 1, 0);
+                         MIN_CHECK | MAX_CHECK, 1,
+                         inodes_per_block * blocks_per_group);
        check_super_value(ctx, "r_blocks_count", s->s_r_blocks_count,
                          MAX_CHECK, 0, s->s_blocks_count);
 
@@ -151,6 +144,16 @@ void check_super_block(e2fsck_t ctx)
                return;
        }
 
+       should_be = s->s_inodes_per_group * fs->group_desc_count;
+       if (s->s_inodes_count != should_be) {
+               pctx.ino = s->s_inodes_count;
+               pctx.ino2 = should_be;
+               if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
+                       s->s_inodes_count = should_be;
+                       ext2fs_mark_super_dirty(fs);
+               }
+       }
+
        /*
         * Verify the group descriptors....
         */
@@ -202,18 +205,33 @@ void check_super_block(e2fsck_t ctx)
                ext2fs_mark_super_dirty(fs);
        }
 
+       clear_problem_context(&pctx);
+       
 #ifndef EXT2_SKIP_UUID
        /*
         * If the UUID field isn't assigned, assign it.
         */
        if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(s->s_uuid)) {
-               clear_problem_context(&pctx);
                if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
                        uuid_generate(s->s_uuid);
                        ext2fs_mark_super_dirty(fs);
                }
        }
 #endif
+       
+       /*
+        * For the Hurd, check to see if the filetype option is set,
+        * since it doesn't support it.
+        */
+       if (fs->super->s_creator_os == EXT2_OS_HURD &&
+           (fs->super->s_feature_incompat &
+            EXT2_FEATURE_INCOMPAT_FILETYPE)) {
+               if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
+                       fs->super->s_feature_incompat &=
+                               ~EXT2_FEATURE_INCOMPAT_FILETYPE;
+                       ext2fs_mark_super_dirty(fs);
+
+               }
+       }
        return;
 }
-