diff options
-rw-r--r-- | fs/ext4/balloc.c | 6 | ||||
-rw-r--r-- | fs/ext4/inode.c | 8 | ||||
-rw-r--r-- | fs/ext4/super.c | 18 | ||||
-rw-r--r-- | include/linux/ext4_fs.h | 9 | ||||
-rw-r--r-- | include/linux/ext4_fs_sb.h | 1 |
5 files changed, 31 insertions, 11 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index df77ea891f29..3dacb124b8c8 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -74,10 +74,12 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, | |||
74 | return NULL; | 74 | return NULL; |
75 | } | 75 | } |
76 | 76 | ||
77 | desc = (struct ext4_group_desc *) sbi->s_group_desc[group_desc]->b_data; | 77 | desc = (struct ext4_group_desc *)( |
78 | (__u8 *)sbi->s_group_desc[group_desc]->b_data + | ||
79 | offset * EXT4_DESC_SIZE(sb)); | ||
78 | if (bh) | 80 | if (bh) |
79 | *bh = sbi->s_group_desc[group_desc]; | 81 | *bh = sbi->s_group_desc[group_desc]; |
80 | return desc + offset; | 82 | return desc; |
81 | } | 83 | } |
82 | 84 | ||
83 | /** | 85 | /** |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c05dc57148bb..d03e7d85a638 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2432,14 +2432,16 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, | |||
2432 | return 0; | 2432 | return 0; |
2433 | } | 2433 | } |
2434 | 2434 | ||
2435 | gdp = (struct ext4_group_desc *)bh->b_data; | 2435 | gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data + |
2436 | desc * EXT4_DESC_SIZE(sb)); | ||
2436 | /* | 2437 | /* |
2437 | * Figure out the offset within the block group inode table | 2438 | * Figure out the offset within the block group inode table |
2438 | */ | 2439 | */ |
2439 | offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * | 2440 | offset = ((ino - 1) % EXT4_INODES_PER_GROUP(sb)) * |
2440 | EXT4_INODE_SIZE(sb); | 2441 | EXT4_INODE_SIZE(sb); |
2441 | block = ext4_inode_table(gdp + desc) + | 2442 | block = ext4_inode_table(gdp) + (offset >> EXT4_BLOCK_SIZE_BITS(sb)); |
2442 | (offset >> EXT4_BLOCK_SIZE_BITS(sb)); | 2443 | |
2444 | |||
2443 | 2445 | ||
2444 | iloc->block_group = block_group; | 2446 | iloc->block_group = block_group; |
2445 | iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); | 2447 | iloc->offset = offset & (EXT4_BLOCK_SIZE(sb) - 1); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d844175e60e8..bc8848bff2f1 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1268,7 +1268,8 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1268 | return 0; | 1268 | return 0; |
1269 | } | 1269 | } |
1270 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 1270 | first_block += EXT4_BLOCKS_PER_GROUP(sb); |
1271 | gdp++; | 1271 | gdp = (struct ext4_group_desc *) |
1272 | ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); | ||
1272 | } | 1273 | } |
1273 | 1274 | ||
1274 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); | 1275 | 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 | sbi->s_frag_size, blocksize); | 1620 | sbi->s_frag_size, blocksize); |
1620 | goto failed_mount; | 1621 | goto failed_mount; |
1621 | } | 1622 | } |
1622 | sbi->s_frags_per_block = 1; | 1623 | sbi->s_desc_size = le16_to_cpu(es->s_desc_size); |
1624 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { | ||
1625 | if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE || | ||
1626 | sbi->s_desc_size > EXT4_MAX_DESC_SIZE || | ||
1627 | sbi->s_desc_size & (sbi->s_desc_size - 1)) { | ||
1628 | printk(KERN_ERR | ||
1629 | "EXT4-fs: unsupported descriptor size %ld\n", | ||
1630 | sbi->s_desc_size); | ||
1631 | goto failed_mount; | ||
1632 | } | ||
1633 | } else | ||
1634 | sbi->s_desc_size = EXT4_MIN_DESC_SIZE; | ||
1623 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); | 1635 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); |
1624 | sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); | 1636 | sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); |
1625 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); | 1637 | 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 | goto cantfind_ext4; | 1642 | goto cantfind_ext4; |
1631 | sbi->s_itb_per_group = sbi->s_inodes_per_group / | 1643 | sbi->s_itb_per_group = sbi->s_inodes_per_group / |
1632 | sbi->s_inodes_per_block; | 1644 | sbi->s_inodes_per_block; |
1633 | sbi->s_desc_per_block = blocksize / sizeof(struct ext4_group_desc); | 1645 | sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb); |
1634 | sbi->s_sbh = bh; | 1646 | sbi->s_sbh = bh; |
1635 | sbi->s_mount_state = le16_to_cpu(es->s_state); | 1647 | sbi->s_mount_state = le16_to_cpu(es->s_state); |
1636 | sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb)); | 1648 | sbi->s_addr_per_block_bits = log2(EXT4_ADDR_PER_BLOCK(sb)); |
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index 8e5009ee4ad8..a3df2afc004b 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h | |||
@@ -142,6 +142,9 @@ struct ext4_group_desc | |||
142 | /* | 142 | /* |
143 | * Macro-instructions used to manage group descriptors | 143 | * Macro-instructions used to manage group descriptors |
144 | */ | 144 | */ |
145 | #define EXT4_MIN_DESC_SIZE 32 | ||
146 | #define EXT4_MAX_DESC_SIZE EXT4_MIN_BLOCK_SIZE | ||
147 | #define EXT4_DESC_SIZE(s) (EXT4_SB(s)->s_desc_size) | ||
145 | #ifdef __KERNEL__ | 148 | #ifdef __KERNEL__ |
146 | # define EXT4_BLOCKS_PER_GROUP(s) (EXT4_SB(s)->s_blocks_per_group) | 149 | # define EXT4_BLOCKS_PER_GROUP(s) (EXT4_SB(s)->s_blocks_per_group) |
147 | # define EXT4_DESC_PER_BLOCK(s) (EXT4_SB(s)->s_desc_per_block) | 150 | # define EXT4_DESC_PER_BLOCK(s) (EXT4_SB(s)->s_desc_per_block) |
@@ -149,7 +152,7 @@ struct ext4_group_desc | |||
149 | # define EXT4_DESC_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_desc_per_block_bits) | 152 | # define EXT4_DESC_PER_BLOCK_BITS(s) (EXT4_SB(s)->s_desc_per_block_bits) |
150 | #else | 153 | #else |
151 | # define EXT4_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) | 154 | # define EXT4_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) |
152 | # define EXT4_DESC_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / sizeof (struct ext4_group_desc)) | 155 | # define EXT4_DESC_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_DESC_SIZE(s)) |
153 | # define EXT4_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) | 156 | # define EXT4_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) |
154 | #endif | 157 | #endif |
155 | 158 | ||
@@ -474,7 +477,7 @@ struct ext4_super_block { | |||
474 | * things it doesn't understand... | 477 | * things it doesn't understand... |
475 | */ | 478 | */ |
476 | __le32 s_first_ino; /* First non-reserved inode */ | 479 | __le32 s_first_ino; /* First non-reserved inode */ |
477 | __le16 s_inode_size; /* size of inode structure */ | 480 | __le16 s_inode_size; /* size of inode structure */ |
478 | __le16 s_block_group_nr; /* block group # of this superblock */ | 481 | __le16 s_block_group_nr; /* block group # of this superblock */ |
479 | __le32 s_feature_compat; /* compatible feature set */ | 482 | __le32 s_feature_compat; /* compatible feature set */ |
480 | /*60*/ __le32 s_feature_incompat; /* incompatible feature set */ | 483 | /*60*/ __le32 s_feature_incompat; /* incompatible feature set */ |
@@ -500,7 +503,7 @@ struct ext4_super_block { | |||
500 | __le32 s_hash_seed[4]; /* HTREE hash seed */ | 503 | __le32 s_hash_seed[4]; /* HTREE hash seed */ |
501 | __u8 s_def_hash_version; /* Default hash version to use */ | 504 | __u8 s_def_hash_version; /* Default hash version to use */ |
502 | __u8 s_reserved_char_pad; | 505 | __u8 s_reserved_char_pad; |
503 | __u16 s_reserved_word_pad; | 506 | __le16 s_desc_size; /* size of group descriptor */ |
504 | /*100*/ __le32 s_default_mount_opts; | 507 | /*100*/ __le32 s_default_mount_opts; |
505 | __le32 s_first_meta_bg; /* First metablock block group */ | 508 | __le32 s_first_meta_bg; /* First metablock block group */ |
506 | __le32 s_mkfs_time; /* When the filesystem was created */ | 509 | __le32 s_mkfs_time; /* When the filesystem was created */ |
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h index ce7a844d6703..691a713139ce 100644 --- a/include/linux/ext4_fs_sb.h +++ b/include/linux/ext4_fs_sb.h | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | struct ext4_sb_info { | 30 | struct ext4_sb_info { |
31 | unsigned long s_frag_size; /* Size of a fragment in bytes */ | 31 | unsigned long s_frag_size; /* Size of a fragment in bytes */ |
32 | unsigned long s_desc_size; /* Size of a group descriptor in bytes */ | ||
32 | unsigned long s_frags_per_block;/* Number of fragments per block */ | 33 | unsigned long s_frags_per_block;/* Number of fragments per block */ |
33 | unsigned long s_inodes_per_block;/* Number of inodes per block */ | 34 | unsigned long s_inodes_per_block;/* Number of inodes per block */ |
34 | unsigned long s_frags_per_group;/* Number of fragments in a group */ | 35 | unsigned long s_frags_per_group;/* Number of fragments in a group */ |