@@ -1900,6 +1900,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
19001900 }
19011901 sbi -> s_commit_interval = HZ * arg ;
19021902 } else if (token == Opt_debug_want_extra_isize ) {
1903+ if ((arg & 1 ) ||
1904+ (arg < 4 ) ||
1905+ (arg > (sbi -> s_inode_size - EXT4_GOOD_OLD_INODE_SIZE ))) {
1906+ ext4_msg (sb , KERN_ERR ,
1907+ "Invalid want_extra_isize %d" , arg );
1908+ return -1 ;
1909+ }
19031910 sbi -> s_want_extra_isize = arg ;
19041911 } else if (token == Opt_max_batch_time ) {
19051912 sbi -> s_max_batch_time = arg ;
@@ -3554,40 +3561,6 @@ int ext4_calculate_overhead(struct super_block *sb)
35543561 return 0 ;
35553562}
35563563
3557- static void ext4_clamp_want_extra_isize (struct super_block * sb )
3558- {
3559- struct ext4_sb_info * sbi = EXT4_SB (sb );
3560- struct ext4_super_block * es = sbi -> s_es ;
3561- unsigned def_extra_isize = sizeof (struct ext4_inode ) -
3562- EXT4_GOOD_OLD_INODE_SIZE ;
3563-
3564- if (sbi -> s_inode_size == EXT4_GOOD_OLD_INODE_SIZE ) {
3565- sbi -> s_want_extra_isize = 0 ;
3566- return ;
3567- }
3568- if (sbi -> s_want_extra_isize < 4 ) {
3569- sbi -> s_want_extra_isize = def_extra_isize ;
3570- if (ext4_has_feature_extra_isize (sb )) {
3571- if (sbi -> s_want_extra_isize <
3572- le16_to_cpu (es -> s_want_extra_isize ))
3573- sbi -> s_want_extra_isize =
3574- le16_to_cpu (es -> s_want_extra_isize );
3575- if (sbi -> s_want_extra_isize <
3576- le16_to_cpu (es -> s_min_extra_isize ))
3577- sbi -> s_want_extra_isize =
3578- le16_to_cpu (es -> s_min_extra_isize );
3579- }
3580- }
3581- /* Check if enough inode space is available */
3582- if ((sbi -> s_want_extra_isize > sbi -> s_inode_size ) ||
3583- (EXT4_GOOD_OLD_INODE_SIZE + sbi -> s_want_extra_isize >
3584- sbi -> s_inode_size )) {
3585- sbi -> s_want_extra_isize = def_extra_isize ;
3586- ext4_msg (sb , KERN_INFO ,
3587- "required extra inode space not available" );
3588- }
3589- }
3590-
35913564static void ext4_set_resv_clusters (struct super_block * sb )
35923565{
35933566 ext4_fsblk_t resv_clusters ;
@@ -3795,6 +3768,68 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
37953768 */
37963769 sbi -> s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT ;
37973770
3771+ if (le32_to_cpu (es -> s_rev_level ) == EXT4_GOOD_OLD_REV ) {
3772+ sbi -> s_inode_size = EXT4_GOOD_OLD_INODE_SIZE ;
3773+ sbi -> s_first_ino = EXT4_GOOD_OLD_FIRST_INO ;
3774+ } else {
3775+ sbi -> s_inode_size = le16_to_cpu (es -> s_inode_size );
3776+ sbi -> s_first_ino = le32_to_cpu (es -> s_first_ino );
3777+ if (sbi -> s_first_ino < EXT4_GOOD_OLD_FIRST_INO ) {
3778+ ext4_msg (sb , KERN_ERR , "invalid first ino: %u" ,
3779+ sbi -> s_first_ino );
3780+ goto failed_mount ;
3781+ }
3782+ if ((sbi -> s_inode_size < EXT4_GOOD_OLD_INODE_SIZE ) ||
3783+ (!is_power_of_2 (sbi -> s_inode_size )) ||
3784+ (sbi -> s_inode_size > blocksize )) {
3785+ ext4_msg (sb , KERN_ERR ,
3786+ "unsupported inode size: %d" ,
3787+ sbi -> s_inode_size );
3788+ goto failed_mount ;
3789+ }
3790+ /*
3791+ * i_atime_extra is the last extra field available for
3792+ * [acm]times in struct ext4_inode. Checking for that
3793+ * field should suffice to ensure we have extra space
3794+ * for all three.
3795+ */
3796+ if (sbi -> s_inode_size >= offsetof(struct ext4_inode , i_atime_extra ) +
3797+ sizeof (((struct ext4_inode * )0 )-> i_atime_extra )) {
3798+ sb -> s_time_gran = 1 ;
3799+ sb -> s_time_max = EXT4_EXTRA_TIMESTAMP_MAX ;
3800+ } else {
3801+ sb -> s_time_gran = NSEC_PER_SEC ;
3802+ sb -> s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX ;
3803+ }
3804+ sb -> s_time_min = EXT4_TIMESTAMP_MIN ;
3805+ }
3806+ if (sbi -> s_inode_size > EXT4_GOOD_OLD_INODE_SIZE ) {
3807+ sbi -> s_want_extra_isize = sizeof (struct ext4_inode ) -
3808+ EXT4_GOOD_OLD_INODE_SIZE ;
3809+ if (ext4_has_feature_extra_isize (sb )) {
3810+ unsigned v , max = (sbi -> s_inode_size -
3811+ EXT4_GOOD_OLD_INODE_SIZE );
3812+
3813+ v = le16_to_cpu (es -> s_want_extra_isize );
3814+ if (v > max ) {
3815+ ext4_msg (sb , KERN_ERR ,
3816+ "bad s_want_extra_isize: %d" , v );
3817+ goto failed_mount ;
3818+ }
3819+ if (sbi -> s_want_extra_isize < v )
3820+ sbi -> s_want_extra_isize = v ;
3821+
3822+ v = le16_to_cpu (es -> s_min_extra_isize );
3823+ if (v > max ) {
3824+ ext4_msg (sb , KERN_ERR ,
3825+ "bad s_min_extra_isize: %d" , v );
3826+ goto failed_mount ;
3827+ }
3828+ if (sbi -> s_want_extra_isize < v )
3829+ sbi -> s_want_extra_isize = v ;
3830+ }
3831+ }
3832+
37983833 if (sbi -> s_es -> s_mount_opts [0 ]) {
37993834 char * s_mount_opts = kstrndup (sbi -> s_es -> s_mount_opts ,
38003835 sizeof (sbi -> s_es -> s_mount_opts ),
@@ -4033,42 +4068,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
40334068 has_huge_files );
40344069 sb -> s_maxbytes = ext4_max_size (sb -> s_blocksize_bits , has_huge_files );
40354070
4036- if (le32_to_cpu (es -> s_rev_level ) == EXT4_GOOD_OLD_REV ) {
4037- sbi -> s_inode_size = EXT4_GOOD_OLD_INODE_SIZE ;
4038- sbi -> s_first_ino = EXT4_GOOD_OLD_FIRST_INO ;
4039- } else {
4040- sbi -> s_inode_size = le16_to_cpu (es -> s_inode_size );
4041- sbi -> s_first_ino = le32_to_cpu (es -> s_first_ino );
4042- if (sbi -> s_first_ino < EXT4_GOOD_OLD_FIRST_INO ) {
4043- ext4_msg (sb , KERN_ERR , "invalid first ino: %u" ,
4044- sbi -> s_first_ino );
4045- goto failed_mount ;
4046- }
4047- if ((sbi -> s_inode_size < EXT4_GOOD_OLD_INODE_SIZE ) ||
4048- (!is_power_of_2 (sbi -> s_inode_size )) ||
4049- (sbi -> s_inode_size > blocksize )) {
4050- ext4_msg (sb , KERN_ERR ,
4051- "unsupported inode size: %d" ,
4052- sbi -> s_inode_size );
4053- goto failed_mount ;
4054- }
4055- /*
4056- * i_atime_extra is the last extra field available for [acm]times in
4057- * struct ext4_inode. Checking for that field should suffice to ensure
4058- * we have extra space for all three.
4059- */
4060- if (sbi -> s_inode_size >= offsetof(struct ext4_inode , i_atime_extra ) +
4061- sizeof (((struct ext4_inode * )0 )-> i_atime_extra )) {
4062- sb -> s_time_gran = 1 ;
4063- sb -> s_time_max = EXT4_EXTRA_TIMESTAMP_MAX ;
4064- } else {
4065- sb -> s_time_gran = NSEC_PER_SEC ;
4066- sb -> s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX ;
4067- }
4068-
4069- sb -> s_time_min = EXT4_TIMESTAMP_MIN ;
4070- }
4071-
40724071 sbi -> s_desc_size = le16_to_cpu (es -> s_desc_size );
40734072 if (ext4_has_feature_64bit (sb )) {
40744073 if (sbi -> s_desc_size < EXT4_MIN_DESC_SIZE_64BIT ||
@@ -4517,8 +4516,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
45174516 } else if (ret )
45184517 goto failed_mount4a ;
45194518
4520- ext4_clamp_want_extra_isize (sb );
4521-
45224519 ext4_set_resv_clusters (sb );
45234520
45244521 err = ext4_setup_system_zone (sb );
@@ -5306,8 +5303,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
53065303 goto restore_opts ;
53075304 }
53085305
5309- ext4_clamp_want_extra_isize (sb );
5310-
53115306 if ((old_opts .s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM ) ^
53125307 test_opt (sb , JOURNAL_CHECKSUM )) {
53135308 ext4_msg (sb , KERN_ERR , "changing journal_checksum "
0 commit comments