| Message ID | 20251025032221.2905818-25-libaokun@huaweicloud.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series | ext4: enable block size larger than page size | expand |
On Sat 25-10-25 11:22:20, libaokun@huaweicloud.com wrote: > From: Baokun Li <libaokun1@huawei.com> > > Supporting a block size greater than the page size (BS > PS) requires > support for large folios. However, several features (e.g., verity, encrypt) > and mount options (e.g., data=journal) do not yet support large folios. > > To prevent conflicts, this patch adds checks at mount time to prohibit > these features and options from being used when BS > PS. Since the data > mode cannot be changed on remount, there is no need to check on remount. > > A new mount flag, EXT4_MF_LARGE_FOLIO, is introduced. This flag is set > after the checks pass, indicating that the filesystem has no features or > mount options incompatible with large folios. Subsequent checks can simply > test for this flag to avoid redundant verifications. > > Signed-off-by: Baokun Li <libaokun1@huawei.com> > Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Looks good. Feel free to add: Reviewed-by: Jan Kara <jack@suse.cz> Honza > --- > fs/ext4/ext4.h | 3 ++- > fs/ext4/inode.c | 10 ++++------ > fs/ext4/super.c | 26 ++++++++++++++++++++++++++ > 3 files changed, 32 insertions(+), 7 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 8223ed29b343..f1163deb0812 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -1859,7 +1859,8 @@ static inline int ext4_get_resgid(struct ext4_super_block *es) > enum { > EXT4_MF_MNTDIR_SAMPLED, > EXT4_MF_FC_INELIGIBLE, /* Fast commit ineligible */ > - EXT4_MF_JOURNAL_DESTROY /* Journal is in process of destroying */ > + EXT4_MF_JOURNAL_DESTROY,/* Journal is in process of destroying */ > + EXT4_MF_LARGE_FOLIO, /* large folio is support */ > }; > > static inline void ext4_set_mount_flag(struct super_block *sb, int bit) > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index b3fa29923a1d..04f9380d4211 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5143,14 +5143,12 @@ static bool ext4_should_enable_large_folio(struct inode *inode) > { > struct super_block *sb = inode->i_sb; > > - if (!S_ISREG(inode->i_mode)) > - return false; > - if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || > - ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) > + if (!ext4_test_mount_flag(sb, EXT4_MF_LARGE_FOLIO)) > return false; > - if (ext4_has_feature_verity(sb)) > + > + if (!S_ISREG(inode->i_mode)) > return false; > - if (ext4_has_feature_encrypt(sb)) > + if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) > return false; > > return true; > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index 7338c708ea1d..fdc006a973aa 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -5034,6 +5034,28 @@ static const char *ext4_has_journal_option(struct super_block *sb) > return NULL; > } > > +static int ext4_check_large_folio(struct super_block *sb) > +{ > + const char *err_str = NULL; > + > + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) > + err_str = "data=journal"; > + else if (ext4_has_feature_verity(sb)) > + err_str = "verity"; > + else if (ext4_has_feature_encrypt(sb)) > + err_str = "encrypt"; > + > + if (!err_str) { > + ext4_set_mount_flag(sb, EXT4_MF_LARGE_FOLIO); > + } else if (sb->s_blocksize > PAGE_SIZE) { > + ext4_msg(sb, KERN_ERR, "bs(%lu) > ps(%lu) unsupported for %s", > + sb->s_blocksize, PAGE_SIZE, err_str); > + return -EINVAL; > + } > + > + return 0; > +} > + > static int ext4_load_super(struct super_block *sb, ext4_fsblk_t *lsb, > int silent) > { > @@ -5310,6 +5332,10 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) > > ext4_apply_options(fc, sb); > > + err = ext4_check_large_folio(sb); > + if (err < 0) > + goto failed_mount; > + > err = ext4_encoding_init(sb, es); > if (err) > goto failed_mount; > -- > 2.46.1 >
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8223ed29b343..f1163deb0812 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1859,7 +1859,8 @@ static inline int ext4_get_resgid(struct ext4_super_block *es) enum { EXT4_MF_MNTDIR_SAMPLED, EXT4_MF_FC_INELIGIBLE, /* Fast commit ineligible */ - EXT4_MF_JOURNAL_DESTROY /* Journal is in process of destroying */ + EXT4_MF_JOURNAL_DESTROY,/* Journal is in process of destroying */ + EXT4_MF_LARGE_FOLIO, /* large folio is support */ }; static inline void ext4_set_mount_flag(struct super_block *sb, int bit) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b3fa29923a1d..04f9380d4211 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5143,14 +5143,12 @@ static bool ext4_should_enable_large_folio(struct inode *inode) { struct super_block *sb = inode->i_sb; - if (!S_ISREG(inode->i_mode)) - return false; - if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || - ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) + if (!ext4_test_mount_flag(sb, EXT4_MF_LARGE_FOLIO)) return false; - if (ext4_has_feature_verity(sb)) + + if (!S_ISREG(inode->i_mode)) return false; - if (ext4_has_feature_encrypt(sb)) + if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA)) return false; return true; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7338c708ea1d..fdc006a973aa 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -5034,6 +5034,28 @@ static const char *ext4_has_journal_option(struct super_block *sb) return NULL; } +static int ext4_check_large_folio(struct super_block *sb) +{ + const char *err_str = NULL; + + if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) + err_str = "data=journal"; + else if (ext4_has_feature_verity(sb)) + err_str = "verity"; + else if (ext4_has_feature_encrypt(sb)) + err_str = "encrypt"; + + if (!err_str) { + ext4_set_mount_flag(sb, EXT4_MF_LARGE_FOLIO); + } else if (sb->s_blocksize > PAGE_SIZE) { + ext4_msg(sb, KERN_ERR, "bs(%lu) > ps(%lu) unsupported for %s", + sb->s_blocksize, PAGE_SIZE, err_str); + return -EINVAL; + } + + return 0; +} + static int ext4_load_super(struct super_block *sb, ext4_fsblk_t *lsb, int silent) { @@ -5310,6 +5332,10 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) ext4_apply_options(fc, sb); + err = ext4_check_large_folio(sb); + if (err < 0) + goto failed_mount; + err = ext4_encoding_init(sb, es); if (err) goto failed_mount;