[PATCH] ext4: allow larger descriptor size
authorAlexandre Ratchov <alexandre.ratchov@bull.net>
Wed, 11 Oct 2006 08:21:14 +0000 (01:21 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 11 Oct 2006 18:14:18 +0000 (11:14 -0700)
make block group descriptor larger.

Signed-off-by: Alexandre Ratchov <alexandre.ratchov@bull.net>
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/ext4/balloc.c
fs/ext4/inode.c
fs/ext4/super.c
include/linux/ext4_fs.h
include/linux/ext4_fs_sb.h

index df77ea8..3dacb12 100644 (file)
@@ -74,10 +74,12 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
                return NULL;
        }
 
-       desc = (struct ext4_group_desc *) sbi->s_group_desc[group_desc]->b_data;
+       desc = (struct ext4_group_desc *)(
+               (__u8 *)sbi->s_group_desc[group_desc]->b_data +
+               offset * EXT4_DESC_SIZE(sb));
        if (bh)
                *bh = sbi->s_group_desc[group_desc];
-       return desc + offset;
+       return desc;
 }
 
 /**
index c05dc57..d03e7d8 100644 (file)
@@ -2432,14 +2432,16 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,
                return 0;
        }
 
-       gdp = (struct ext4_group_desc *)bh->b_data;
+       gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data +
+               desc * EXT4_DESC_SIZE(sb));
        /*
         * Figure out the offset within the block group inode table
         */
        offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *
                EXT4_INODE_SIZE(sb);
-       block = ext4_inode_table(gdp + desc) +
-                       (offset >> EXT4_BLOCK_SIZE_BITS(sb));
+       block = ext4_inode_table(gdp) + (offset >> EXT4_BLOCK_SIZE_BITS(sb));
+
+
 
        iloc->block_group = block_group;
        iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);
index d844175..bc8848b 100644 (file)
@@ -1268,7 +1268,8 @@ static int ext4_check_descriptors (struct super_block * sb)
                        return 0;
                }
                first_block += EXT4_BLOCKS_PER_GROUP(sb);
-               gdp++;
+               gdp = (struct ext4_group_desc *)
+                       ((__u8 *)gdp + EXT4_DESC_SIZE(sb));
        }
 
        ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb));
@@ -1619,7 +1620,18 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
                       sbi->s_frag_size, blocksize);
                goto failed_mount;
        }
-       sbi->s_frags_per_block = 1;
+       sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
+       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) {
+               if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE ||
+                   sbi->s_desc_size > EXT4_MAX_DESC_SIZE ||
+                   sbi->s_desc_size & (sbi->s_desc_size - 1)) {
+                       printk(KERN_ERR
+                              "EXT4-fs: unsupported descriptor size %ld\n",
+                              sbi->s_desc_size);
+                       goto failed_mount;
+               }
+       } else
+               sbi->s_desc_size = EXT4_MIN_DESC_SIZE;
        sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
        sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group);
        sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
@@ -1630,7 +1642,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
                goto cantfind_ext4;
        sbi->s_itb_per_group = sbi->s_inodes_per_group /
                                        sbi->s_inodes_per_block;
-       sbi->s_desc_per_block = blocksize / sizeof(struct ext4_group_desc);
+       sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
        sbi->s_sbh = bh;
        sbi->s_mount_state = le16_to_cpu(es->s_state);
        sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
index 8e5009e..a3df2af 100644 (file)
@@ -142,6 +142,9 @@ struct ext4_group_desc
 /*
  * Macro-instructions used to manage group descriptors
  */
+#define EXT4_MIN_DESC_SIZE             32
+#define        EXT4_MAX_DESC_SIZE              EXT4_MIN_BLOCK_SIZE
+#define EXT4_DESC_SIZE(s)              (EXT4_SB(s)->s_desc_size)
 #ifdef __KERNEL__
 # define EXT4_BLOCKS_PER_GROUP(s)      (EXT4_SB(s)->s_blocks_per_group)
 # define EXT4_DESC_PER_BLOCK(s)                (EXT4_SB(s)->s_desc_per_block)
@@ -149,7 +152,7 @@ struct ext4_group_desc
 # define EXT4_DESC_PER_BLOCK_BITS(s)   (EXT4_SB(s)->s_desc_per_block_bits)
 #else
 # define EXT4_BLOCKS_PER_GROUP(s)      ((s)->s_blocks_per_group)
-# define EXT4_DESC_PER_BLOCK(s)                (EXT4_BLOCK_SIZE(s) / sizeof (struct ext4_group_desc))
+# define EXT4_DESC_PER_BLOCK(s)                (EXT4_BLOCK_SIZE(s) / EXT4_DESC_SIZE(s))
 # define EXT4_INODES_PER_GROUP(s)      ((s)->s_inodes_per_group)
 #endif
 
@@ -474,7 +477,7 @@ struct ext4_super_block {
         * things it doesn't understand...
         */
        __le32  s_first_ino;            /* First non-reserved inode */
-       __le16   s_inode_size;          /* size of inode structure */
+       __le16  s_inode_size;           /* size of inode structure */
        __le16  s_block_group_nr;       /* block group # of this superblock */
        __le32  s_feature_compat;       /* compatible feature set */
 /*60*/ __le32  s_feature_incompat;     /* incompatible feature set */
@@ -500,7 +503,7 @@ struct ext4_super_block {
        __le32  s_hash_seed[4];         /* HTREE hash seed */
        __u8    s_def_hash_version;     /* Default hash version to use */
        __u8    s_reserved_char_pad;
-       __u16   s_reserved_word_pad;
+       __le16  s_desc_size;            /* size of group descriptor */
 /*100*/        __le32  s_default_mount_opts;
        __le32  s_first_meta_bg;        /* First metablock block group */
        __le32  s_mkfs_time;            /* When the filesystem was created */
index ce7a844..691a713 100644 (file)
@@ -29,6 +29,7 @@
  */
 struct ext4_sb_info {
        unsigned long s_frag_size;      /* Size of a fragment in bytes */
+       unsigned long s_desc_size;      /* Size of a group descriptor in bytes */
        unsigned long s_frags_per_block;/* Number of fragments per block */
        unsigned long s_inodes_per_block;/* Number of inodes per block */
        unsigned long s_frags_per_group;/* Number of fragments in a group */