Commit 7ac67301 authored by Zhang Yi's avatar Zhang Yi Committed by Theodore Ts'o
Browse files

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: default avatarZhang Yi <yi.zhang@huawei.com>
Link: https://patch.msgid.link/20250512063319.3539411-9-yi.zhang@huaweicloud.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 01e807e1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2999,6 +2999,7 @@ int ext4_walk_page_buffers(handle_t *handle,
				     struct buffer_head *bh));
int do_journal_get_write_access(handle_t *handle, struct inode *inode,
				struct buffer_head *bh);
bool ext4_should_enable_large_folio(struct inode *inode);
#define FALL_BACK_TO_NONDELALLOC 1
#define CONVERT_INLINE_DATA	 2

+2 −1
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@ int ext4_inode_journal_mode(struct inode *inode)
	    ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE) ||
	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
	    (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
	    !test_opt(inode->i_sb, DELALLOC))) {
	    !test_opt(inode->i_sb, DELALLOC) &&
	    !mapping_large_folio_support(inode->i_mapping))) {
		/* We do not support data journalling for encrypted data */
		if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
			return EXT4_INODE_ORDERED_DATA_MODE;  /* ordered */
+3 −0
Original line number Diff line number Diff line
@@ -1336,6 +1336,9 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
		}
	}

	if (ext4_should_enable_large_folio(inode))
		mapping_set_large_folios(inode->i_mapping);

	ext4_update_inode_fsync_trans(handle, inode, 1);

	err = ext4_mark_inode_dirty(handle, inode);
+20 −0
Original line number Diff line number Diff line
@@ -4829,6 +4829,23 @@ static int check_igot_inode(struct inode *inode, ext4_iget_flags flags,
	return -EFSCORRUPTED;
}

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))
		return false;
	if (ext4_has_feature_verity(sb))
		return false;
	if (ext4_has_feature_encrypt(sb))
		return false;

	return true;
}

struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
			  ext4_iget_flags flags, const char *function,
			  unsigned int line)
@@ -5147,6 +5164,9 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
		ret = -EFSCORRUPTED;
		goto bad_inode;
	}
	if (ext4_should_enable_large_folio(inode))
		mapping_set_large_folios(inode->i_mapping);

	ret = check_igot_inode(inode, flags, function, line);
	/*
	 * -ESTALE here means there is nothing inherently wrong with the inode,