Commit 0d1ee42f authored by Alexandre Ratchov's avatar Alexandre Ratchov Committed by Linus Torvalds

[PATCH] ext4: allow larger descriptor size

make block group descriptor larger.
Signed-off-by: default avatarAlexandre Ratchov <alexandre.ratchov@bull.net>
Signed-off-by: default avatarDave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 18eba7aa
...@@ -74,10 +74,12 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, ...@@ -74,10 +74,12 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
return NULL; 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) if (bh)
*bh = sbi->s_group_desc[group_desc]; *bh = sbi->s_group_desc[group_desc];
return desc + offset; return desc;
} }
/** /**
......
...@@ -2432,14 +2432,16 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, ...@@ -2432,14 +2432,16 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,
return 0; 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 * Figure out the offset within the block group inode table
*/ */
offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) *
EXT4_INODE_SIZE(sb); EXT4_INODE_SIZE(sb);
block = ext4_inode_table(gdp + desc) + block = ext4_inode_table(gdp) + (offset >> EXT4_BLOCK_SIZE_BITS(sb));
(offset >> EXT4_BLOCK_SIZE_BITS(sb));
iloc->block_group = block_group; iloc->block_group = block_group;
iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1);
......
...@@ -1268,7 +1268,8 @@ static int ext4_check_descriptors (struct super_block * sb) ...@@ -1268,7 +1268,8 @@ static int ext4_check_descriptors (struct super_block * sb)
return 0; return 0;
} }
first_block += EXT4_BLOCKS_PER_GROUP(sb); 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)); 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) ...@@ -1619,7 +1620,18 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
sbi->s_frag_size, blocksize); sbi->s_frag_size, blocksize);
goto failed_mount; 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_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_frags_per_group = le32_to_cpu(es->s_frags_per_group);
sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_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) ...@@ -1630,7 +1642,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent)
goto cantfind_ext4; goto cantfind_ext4;
sbi->s_itb_per_group = sbi->s_inodes_per_group / sbi->s_itb_per_group = sbi->s_inodes_per_group /
sbi->s_inodes_per_block; 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_sbh = bh;
sbi->s_mount_state = le16_to_cpu(es->s_state); sbi->s_mount_state = le16_to_cpu(es->s_state);
sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb)); sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb));
......
...@@ -142,6 +142,9 @@ struct ext4_group_desc ...@@ -142,6 +142,9 @@ struct ext4_group_desc
/* /*
* Macro-instructions used to manage group descriptors * 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__ #ifdef __KERNEL__
# define EXT4_BLOCKS_PER_GROUP(s) (EXT4_SB(s)->s_blocks_per_group) # 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) # define EXT4_DESC_PER_BLOCK(s) (EXT4_SB(s)->s_desc_per_block)
...@@ -149,7 +152,7 @@ struct ext4_group_desc ...@@ -149,7 +152,7 @@ struct ext4_group_desc
# define EXT4_DESC_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_desc_per_block_bits) # define EXT4_DESC_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_desc_per_block_bits)
#else #else
# define EXT4_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) # 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) # define EXT4_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
#endif #endif
...@@ -474,7 +477,7 @@ struct ext4_super_block { ...@@ -474,7 +477,7 @@ struct ext4_super_block {
* things it doesn't understand... * things it doesn't understand...
*/ */
__le32 s_first_ino; /* First non-reserved inode */ __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 */ __le16 s_block_group_nr; /* block group # of this superblock */
__le32 s_feature_compat; /* compatible feature set */ __le32 s_feature_compat; /* compatible feature set */
/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ /*60*/ __le32 s_feature_incompat; /* incompatible feature set */
...@@ -500,7 +503,7 @@ struct ext4_super_block { ...@@ -500,7 +503,7 @@ struct ext4_super_block {
__le32 s_hash_seed[4]; /* HTREE hash seed */ __le32 s_hash_seed[4]; /* HTREE hash seed */
__u8 s_def_hash_version; /* Default hash version to use */ __u8 s_def_hash_version; /* Default hash version to use */
__u8 s_reserved_char_pad; __u8 s_reserved_char_pad;
__u16 s_reserved_word_pad; __le16 s_desc_size; /* size of group descriptor */
/*100*/ __le32 s_default_mount_opts; /*100*/ __le32 s_default_mount_opts;
__le32 s_first_meta_bg; /* First metablock block group */ __le32 s_first_meta_bg; /* First metablock block group */
__le32 s_mkfs_time; /* When the filesystem was created */ __le32 s_mkfs_time; /* When the filesystem was created */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
struct ext4_sb_info { struct ext4_sb_info {
unsigned long s_frag_size; /* Size of a fragment in bytes */ 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_frags_per_block;/* Number of fragments per block */
unsigned long s_inodes_per_block;/* Number of inodes 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 */ unsigned long s_frags_per_group;/* Number of fragments in a group */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment