Skip to content

Commit 7ac6730

Browse files
zhangyi089tytso
authored andcommitted
ext4: enable large folio for regular file
Besides fsverity, fscrypt, and the data=journal mode, ext4 now supports large folios for regular files. Enable this feature by default. However, since we cannot change the folio order limitation of mappings on active inodes, setting the journal=data mode via ioctl on an active inode will not take immediate effect in non-delalloc mode. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20250512063319.3539411-9-yi.zhang@huaweicloud.com Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 01e807e commit 7ac6730

4 files changed

Lines changed: 26 additions & 1 deletion

File tree

fs/ext4/ext4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,6 +2999,7 @@ int ext4_walk_page_buffers(handle_t *handle,
29992999
struct buffer_head *bh));
30003000
int do_journal_get_write_access(handle_t *handle, struct inode *inode,
30013001
struct buffer_head *bh);
3002+
bool ext4_should_enable_large_folio(struct inode *inode);
30023003
#define FALL_BACK_TO_NONDELALLOC 1
30033004
#define CONVERT_INLINE_DATA 2
30043005

fs/ext4/ext4_jbd2.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ int ext4_inode_journal_mode(struct inode *inode)
1616
ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE) ||
1717
test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
1818
(ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
19-
!test_opt(inode->i_sb, DELALLOC))) {
19+
!test_opt(inode->i_sb, DELALLOC) &&
20+
!mapping_large_folio_support(inode->i_mapping))) {
2021
/* We do not support data journalling for encrypted data */
2122
if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
2223
return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */

fs/ext4/ialloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,9 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
13361336
}
13371337
}
13381338

1339+
if (ext4_should_enable_large_folio(inode))
1340+
mapping_set_large_folios(inode->i_mapping);
1341+
13391342
ext4_update_inode_fsync_trans(handle, inode, 1);
13401343

13411344
err = ext4_mark_inode_dirty(handle, inode);

fs/ext4/inode.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4829,6 +4829,23 @@ static int check_igot_inode(struct inode *inode, ext4_iget_flags flags,
48294829
return -EFSCORRUPTED;
48304830
}
48314831

4832+
bool ext4_should_enable_large_folio(struct inode *inode)
4833+
{
4834+
struct super_block *sb = inode->i_sb;
4835+
4836+
if (!S_ISREG(inode->i_mode))
4837+
return false;
4838+
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
4839+
ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
4840+
return false;
4841+
if (ext4_has_feature_verity(sb))
4842+
return false;
4843+
if (ext4_has_feature_encrypt(sb))
4844+
return false;
4845+
4846+
return true;
4847+
}
4848+
48324849
struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
48334850
ext4_iget_flags flags, const char *function,
48344851
unsigned int line)
@@ -5147,6 +5164,9 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
51475164
ret = -EFSCORRUPTED;
51485165
goto bad_inode;
51495166
}
5167+
if (ext4_should_enable_large_folio(inode))
5168+
mapping_set_large_folios(inode->i_mapping);
5169+
51505170
ret = check_igot_inode(inode, flags, function, line);
51515171
/*
51525172
* -ESTALE here means there is nothing inherently wrong with the inode,

0 commit comments

Comments
 (0)