Whamcloud - gitweb
Do sanity checking of the number of blocks and inodes in a group for
authorAndreas Dilger <adilger@clusterfs.com>
Mon, 10 Jun 2002 17:05:56 +0000 (11:05 -0600)
committerAndreas Dilger <adilger@clusterfs.com>
Mon, 10 Jun 2002 17:05:56 +0000 (11:05 -0600)
8192-byte and 16384-byte blocksize filesystems.

Change the default bytes-per-inode ratio of a new filesystem to be at most
one inode per block for large blocksizes.

17 files changed:
e2fsck/ChangeLog
e2fsck/super.c
lib/ext2fs/ChangeLog
lib/ext2fs/ext2_fs.h
lib/ext2fs/initialize.c
lib/ext2fs/openfs.c
misc/ChangeLog
misc/mke2fs.c
tests/ChangeLog
tests/f_16384_block/expect.1 [new file with mode: 0644]
tests/f_16384_block/expect.2 [new file with mode: 0644]
tests/f_16384_block/image.gz [new file with mode: 0644]
tests/f_16384_block/name [new file with mode: 0644]
tests/f_8192_block/expect.1 [new file with mode: 0644]
tests/f_8192_block/expect.2 [new file with mode: 0644]
tests/f_8192_block/image.gz [new file with mode: 0644]
tests/f_8192_block/name [new file with mode: 0644]

index 5952bdc..c2e7e8d 100644 (file)
@@ -1,3 +1,10 @@
+2002-05-22  Andreas Dilger <adilger@clusterfs.com>
+
+       * super.c (check_superblock): Check that the number of inodes and
+               blocks in a group is less than 2^16, so that the free inode
+               and block counts for a group fit into the group descriptor
+               table fields.  Any more than that would need a COMPAT flag.
+
 2002-05-22  Theodore Ts'o  <tytso@mit.edu>
 
        * pass1.c (check_ext_attr): Update to support the V2 Bestbits EA
index c880a9a..49e9750 100644 (file)
@@ -308,13 +308,20 @@ void check_super_block(e2fsck_t ctx)
        blk_t   first_block, last_block;
        struct ext2_super_block *sb = fs->super;
        blk_t   blocks_per_group = fs->super->s_blocks_per_group;
+       blk_t   bpg_max;
        int     inodes_per_block;
+       int     ipg_max;
        dgrp_t  i;
        blk_t   should_be;
        struct problem_context  pctx;
-       
-       inodes_per_block = (EXT2_BLOCK_SIZE(fs->super) /
-                           EXT2_INODE_SIZE(fs->super));
+
+       inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
+       ipg_max = inodes_per_block * (blocks_per_group - 4);
+       if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
+               ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
+       bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
+       if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
+               bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
 
        ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
                 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
@@ -322,7 +329,7 @@ void check_super_block(e2fsck_t ctx)
                 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
        ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
                sizeof(int) * fs->group_desc_count, "invalid_inode_table");
-               
+
        clear_problem_context(&pctx);
 
        /*
@@ -341,12 +348,11 @@ void check_super_block(e2fsck_t ctx)
                          MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
        check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
                          MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
-                         8 * EXT2_BLOCK_SIZE(sb));
+                         bpg_max);
        check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
-                         MIN_CHECK | MAX_CHECK, 8, 8 * EXT2_BLOCK_SIZE(sb));
+                         MIN_CHECK | MAX_CHECK, 8, bpg_max);
        check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
-                         MIN_CHECK | MAX_CHECK, inodes_per_block,
-                         inodes_per_block * (blocks_per_group-4));
+                         MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
        check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
                          MAX_CHECK, 0, sb->s_blocks_count / 4);
 
index 77ed4cc..0b31f83 100644 (file)
@@ -1,5 +1,18 @@
 2002-06-09  Andreas Dilger <adilger@clusterfs.com>
 
+       * ext2_fs.h: Add macros for maximum block/inode counts:
+               EXT2_INODES_PER_BLOCK, EXT2_MAX_BLOCKS_PER_GROUP,
+               and EXT2_MAX_INODES_PER_GROUP.
+
+       * openfs.c (ext2fs_open): Check that the number of blocks in a group
+               is less than 2^16, otherwise we need an INCOMPAT flag (not
+               in existence yet, if ever) to open such a filesystem.
+
+       * initialize.c (ext2fs_initialize): Limit the number of blocks and
+               inodes in a group to less than 2^16.
+
+2002-06-09  Andreas Dilger <adilger@clusterfs.com>
+
        * ext2_fs.h: Further minor cleanups of the header.  Consolidate
                some checks for __KERNEL__ into one place.
 
index c9033b1..766afd7 100644 (file)
@@ -181,15 +181,17 @@ struct ext2_dx_countlimit {
 /*
  * Macro-instructions used to manage group descriptors
  */
+#define EXT2_BLOCKS_PER_GROUP(s)       (EXT2_SB(s)->s_blocks_per_group)
+#define EXT2_INODES_PER_GROUP(s)       (EXT2_SB(s)->s_inodes_per_group)
+#define EXT2_INODES_PER_BLOCK(s)       (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
+/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
+#define EXT2_MAX_BLOCKS_PER_GROUP(s)   ((1 << 16) - 8)
+#define EXT2_MAX_INODES_PER_GROUP(s)   ((1 << 16) - EXT2_INODES_PER_BLOCK(s))
 #ifdef __KERNEL__
-# define EXT2_BLOCKS_PER_GROUP(s)      (EXT2_SB(s)->s_blocks_per_group)
-# define EXT2_DESC_PER_BLOCK(s)                (EXT2_SB(s)->s_desc_per_block)
-# define EXT2_INODES_PER_GROUP(s)      (EXT2_SB(s)->s_inodes_per_group)
-# define EXT2_DESC_PER_BLOCK_BITS(s)   (EXT2_SB(s)->s_desc_per_block_bits)
+#define EXT2_DESC_PER_BLOCK(s)         (EXT2_SB(s)->s_desc_per_block)
+#define EXT2_DESC_PER_BLOCK_BITS(s)    (EXT2_SB(s)->s_desc_per_block_bits)
 #else
-# define EXT2_BLOCKS_PER_GROUP(s)      ((s)->s_blocks_per_group)
-# define EXT2_DESC_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
-# define EXT2_INODES_PER_GROUP(s)      ((s)->s_inodes_per_group)
+#define EXT2_DESC_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
 #endif
 
 /*
index bf64c68..f132416 100644 (file)
@@ -63,6 +63,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        int             rem;
        int             overhead = 0;
        blk_t           group_block;
+       int             ipg;
        int             i, j;
        blk_t           numblocks;
        char            *buf;
@@ -131,9 +132,11 @@ errcode_t ext2fs_initialize(const char *name, int flags,
        fs->blocksize = EXT2_BLOCK_SIZE(super);
        fs->fragsize = EXT2_FRAG_SIZE(super);
        frags_per_block = fs->blocksize / fs->fragsize;
-       
-       /* default: (fs->blocksize*8) blocks/group */
-       set_field(s_blocks_per_group, fs->blocksize*8); 
+
+       /* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
+       set_field(s_blocks_per_group, fs->blocksize * 8);
+       if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
+               super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
        super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
        
        super->s_blocks_count = param->s_blocks_count;
@@ -180,14 +183,20 @@ retry:
         * There should be at least as many inodes as the user
         * requested.  Figure out how many inodes per group that
         * should be.  But make sure that we don't allocate more than
-        * one bitmap's worth of inodes
+        * one bitmap's worth of inodes each group.
         */
-       super->s_inodes_per_group = (super->s_inodes_count +
-                                    fs->group_desc_count - 1) /
-                                            fs->group_desc_count;
-       if (super->s_inodes_per_group > fs->blocksize*8)
-               super->s_inodes_per_group = fs->blocksize*8;
-       
+       ipg = (super->s_inodes_count + fs->group_desc_count - 1) /
+               fs->group_desc_count;
+       if (ipg > fs->blocksize * 8)
+               ipg = fs->blocksize * 8;
+
+       if (ipg > EXT2_MAX_INODES_PER_GROUP(super))
+               ipg = EXT2_MAX_INODES_PER_GROUP(super);
+
+       super->s_inodes_per_group = ipg;
+       if (super->s_inodes_count > ipg * fs->group_desc_count)
+               super->s_inodes_count = ipg * fs->group_desc_count;
+
        /*
         * Make sure the number of inodes per group completely fills
         * the inode table blocks in the descriptor.  If not, add some
index f3f849f..d9021d6 100644 (file)
@@ -43,7 +43,7 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
 {
        ext2_filsys     fs;
        errcode_t       retval;
-       int             i, j, groups_per_block;
+       int             i, j, groups_per_block, blocks_per_group;
        blk_t           group_block;
        char            *dest;
        struct ext2_group_desc *gdp;
@@ -196,14 +196,16 @@ errcode_t ext2fs_open(const char *name, int flags, int superblock,
        /*
         * Read group descriptors
         */
-       if ((EXT2_BLOCKS_PER_GROUP(fs->super)) == 0) {
+       blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
+       if (blocks_per_group == 0 ||
+           blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
+           fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
                retval = EXT2_ET_CORRUPT_SUPERBLOCK;
                goto cleanup;
        }
        fs->group_desc_count = (fs->super->s_blocks_count -
                                fs->super->s_first_data_block +
-                               EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
-               / EXT2_BLOCKS_PER_GROUP(fs->super);
+                               blocks_per_group - 1) / blocks_per_group;
        fs->desc_blocks = (fs->group_desc_count +
                           EXT2_DESC_PER_BLOCK(fs->super) - 1)
                / EXT2_DESC_PER_BLOCK(fs->super);
index 6bcf531..0a972d0 100644 (file)
@@ -1,3 +1,8 @@
+2002-05-22  Andreas Dilger <adilger@clusterfs.com>
+
+       * mke2fs.c (set_fs_defaults): make the default inode ratio at most
+               one inode per block for large blocksizes.
+
 2002-05-17  Theodore Ts'o  <tytso@mit.edu>
 
        * mke2fs.c (PRS): Determine the page size using sysconf() at
index 4ab4ec3..5625496 100644 (file)
@@ -166,7 +166,8 @@ static void set_fs_defaults(const char *fs_type,
                    (megs > p->size))
                        continue;
                if (ratio == 0)
-                       *inode_ratio = p->inode_ratio;
+                       *inode_ratio = p->inode_ratio < blocksize ?
+                               blocksize : p->inode_ratio;
                if (blocksize == 0) {
                        if (p->blocksize == DEF_MAX_BLOCKSIZE)
                                p->blocksize = sys_page_size;
index 018ef59..9df3d48 100644 (file)
@@ -1,3 +1,8 @@
+2002-06-09  Andreas Dilger  <adilger@clusterfs.com>
+
+       * f_8192_block, f_16384_block: Basic tests of 8192-byte block
+               and 16384-byte blocksize filesystems.
+
 2002-05-21  Theodore Ts'o  <tytso@mit.edu>
 
        * f_badsymlinks: Check for symlink too big error message.
diff --git a/tests/f_16384_block/expect.1 b/tests/f_16384_block/expect.1
new file mode 100644 (file)
index 0000000..d5a5659
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks
+Exit status is 0
diff --git a/tests/f_16384_block/expect.2 b/tests/f_16384_block/expect.2
new file mode 100644 (file)
index 0000000..d5a5659
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks
+Exit status is 0
diff --git a/tests/f_16384_block/image.gz b/tests/f_16384_block/image.gz
new file mode 100644 (file)
index 0000000..c5f311b
Binary files /dev/null and b/tests/f_16384_block/image.gz differ
diff --git a/tests/f_16384_block/name b/tests/f_16384_block/name
new file mode 100644 (file)
index 0000000..79b3112
--- /dev/null
@@ -0,0 +1 @@
+16384 byte blocksize
diff --git a/tests/f_8192_block/expect.1 b/tests/f_8192_block/expect.1
new file mode 100644 (file)
index 0000000..d5a5659
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks
+Exit status is 0
diff --git a/tests/f_8192_block/expect.2 b/tests/f_8192_block/expect.2
new file mode 100644 (file)
index 0000000..d5a5659
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/2048 files (0.0% non-contiguous), 39/1024 blocks
+Exit status is 0
diff --git a/tests/f_8192_block/image.gz b/tests/f_8192_block/image.gz
new file mode 100644 (file)
index 0000000..c5f311b
Binary files /dev/null and b/tests/f_8192_block/image.gz differ
diff --git a/tests/f_8192_block/name b/tests/f_8192_block/name
new file mode 100644 (file)
index 0000000..50d8dca
--- /dev/null
@@ -0,0 +1 @@
+8192 byte blocksize