Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Zhang Yi and committed by
Theodore Ts'o
7ac67301 01e807e1

+26 -1
+1
fs/ext4/ext4.h
··· 2999 2999 struct buffer_head *bh)); 3000 3000 int do_journal_get_write_access(handle_t *handle, struct inode *inode, 3001 3001 struct buffer_head *bh); 3002 + bool ext4_should_enable_large_folio(struct inode *inode); 3002 3003 #define FALL_BACK_TO_NONDELALLOC 1 3003 3004 #define CONVERT_INLINE_DATA 2 3004 3005
+2 -1
fs/ext4/ext4_jbd2.c
··· 16 16 ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE) || 17 17 test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA || 18 18 (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))) { 20 21 /* We do not support data journalling for encrypted data */ 21 22 if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) 22 23 return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
+3
fs/ext4/ialloc.c
··· 1336 1336 } 1337 1337 } 1338 1338 1339 + if (ext4_should_enable_large_folio(inode)) 1340 + mapping_set_large_folios(inode->i_mapping); 1341 + 1339 1342 ext4_update_inode_fsync_trans(handle, inode, 1); 1340 1343 1341 1344 err = ext4_mark_inode_dirty(handle, inode);
+20
fs/ext4/inode.c
··· 4829 4829 return -EFSCORRUPTED; 4830 4830 } 4831 4831 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 + 4832 4849 struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, 4833 4850 ext4_iget_flags flags, const char *function, 4834 4851 unsigned int line) ··· 5164 5147 ret = -EFSCORRUPTED; 5165 5148 goto bad_inode; 5166 5149 } 5150 + if (ext4_should_enable_large_folio(inode)) 5151 + mapping_set_large_folios(inode->i_mapping); 5152 + 5167 5153 ret = check_igot_inode(inode, flags, function, line); 5168 5154 /* 5169 5155 * -ESTALE here means there is nothing inherently wrong with the inode,