Commit b26458d1 authored by Jason Yan's avatar Jason Yan Committed by Theodore Ts'o
Browse files

ext4: factor out ext4_init_metadata_csum()



Factor out ext4_init_metadata_csum(). No functional change.

Signed-off-by: default avatarJason Yan <yanaijie@huawei.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatarRitesh Harjani (IBM) <ritesh.list@gmail.com>
Link: https://lore.kernel.org/r/20220916141527.1012715-9-yanaijie@huawei.com


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 39c135b0
Loading
Loading
Loading
Loading
+46 −37
Original line number Diff line number Diff line
@@ -4540,6 +4540,50 @@ static inline int ext4_encoding_init(struct super_block *sb, struct ext4_super_b
}
#endif

static int ext4_init_metadata_csum(struct super_block *sb, struct ext4_super_block *es)
{
	struct ext4_sb_info *sbi = EXT4_SB(sb);

	/* Warn if metadata_csum and gdt_csum are both set. */
	if (ext4_has_feature_metadata_csum(sb) &&
	    ext4_has_feature_gdt_csum(sb))
		ext4_warning(sb, "metadata_csum and uninit_bg are "
			     "redundant flags; please run fsck.");

	/* Check for a known checksum algorithm */
	if (!ext4_verify_csum_type(sb, es)) {
		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
			 "unknown checksum algorithm.");
		return -EINVAL;
	}
	ext4_setup_csum_trigger(sb, EXT4_JTR_ORPHAN_FILE,
				ext4_orphan_file_block_trigger);

	/* Load the checksum driver */
	sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
	if (IS_ERR(sbi->s_chksum_driver)) {
		int ret = PTR_ERR(sbi->s_chksum_driver);
		ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
		sbi->s_chksum_driver = NULL;
		return ret;
	}

	/* Check superblock checksum */
	if (!ext4_superblock_csum_verify(sb, es)) {
		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
			 "invalid superblock checksum.  Run e2fsck?");
		return -EFSBADCRC;
	}

	/* Precompute checksum seed for all metadata */
	if (ext4_has_feature_csum_seed(sb))
		sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
	else if (ext4_has_metadata_csum(sb) || ext4_has_feature_ea_inode(sb))
		sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
					       sizeof(es->s_uuid));
	return 0;
}

static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
{
	struct buffer_head *bh, **group_desc;
@@ -4609,44 +4653,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)

	sbi->s_kbytes_written = le64_to_cpu(es->s_kbytes_written);

	/* Warn if metadata_csum and gdt_csum are both set. */
	if (ext4_has_feature_metadata_csum(sb) &&
	    ext4_has_feature_gdt_csum(sb))
		ext4_warning(sb, "metadata_csum and uninit_bg are "
			     "redundant flags; please run fsck.");

	/* Check for a known checksum algorithm */
	if (!ext4_verify_csum_type(sb, es)) {
		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
			 "unknown checksum algorithm.");
		goto failed_mount;
	}
	ext4_setup_csum_trigger(sb, EXT4_JTR_ORPHAN_FILE,
				ext4_orphan_file_block_trigger);

	/* Load the checksum driver */
	sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
	if (IS_ERR(sbi->s_chksum_driver)) {
		ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver.");
		ret = PTR_ERR(sbi->s_chksum_driver);
		sbi->s_chksum_driver = NULL;
		goto failed_mount;
	}

	/* Check superblock checksum */
	if (!ext4_superblock_csum_verify(sb, es)) {
		ext4_msg(sb, KERN_ERR, "VFS: Found ext4 filesystem with "
			 "invalid superblock checksum.  Run e2fsck?");
		ret = -EFSBADCRC;
	err = ext4_init_metadata_csum(sb, es);
	if (err)
		goto failed_mount;
	}

	/* Precompute checksum seed for all metadata */
	if (ext4_has_feature_csum_seed(sb))
		sbi->s_csum_seed = le32_to_cpu(es->s_checksum_seed);
	else if (ext4_has_metadata_csum(sb) || ext4_has_feature_ea_inode(sb))
		sbi->s_csum_seed = ext4_chksum(sbi, ~0, es->s_uuid,
					       sizeof(es->s_uuid));

	ext4_set_def_opts(sb, es);