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

ext4: load the crc32c driver if necessary

Obtain a reference to the cryptoapi and crc32c if we mount a
filesystem with metadata checksumming enabled.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>

authored by

Darrick J. Wong and committed by
Theodore Ts'o
0441984a d25425f8

+41
+2
fs/ext4/Kconfig
··· 2 2 tristate "The Extended 4 (ext4) filesystem" 3 3 select JBD2 4 4 select CRC16 5 + select CRYPTO 6 + select CRYPTO_CRC32C 5 7 help 6 8 This is the next generation of the ext3 filesystem. 7 9
+23
fs/ext4/ext4.h
··· 29 29 #include <linux/wait.h> 30 30 #include <linux/blockgroup_lock.h> 31 31 #include <linux/percpu_counter.h> 32 + #include <crypto/hash.h> 32 33 #ifdef __KERNEL__ 33 34 #include <linux/compat.h> 34 35 #endif ··· 1277 1276 1278 1277 /* record the last minlen when FITRIM is called. */ 1279 1278 atomic_t s_last_trim_minblks; 1279 + 1280 + /* Reference to checksum algorithm driver via cryptoapi */ 1281 + struct crypto_shash *s_chksum_driver; 1280 1282 }; 1281 1283 1282 1284 static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) ··· 1642 1638 #define DX_HASH_LEGACY_UNSIGNED 3 1643 1639 #define DX_HASH_HALF_MD4_UNSIGNED 4 1644 1640 #define DX_HASH_TEA_UNSIGNED 5 1641 + 1642 + static inline u32 ext4_chksum(struct ext4_sb_info *sbi, u32 crc, 1643 + const void *address, unsigned int length) 1644 + { 1645 + struct { 1646 + struct shash_desc shash; 1647 + char ctx[crypto_shash_descsize(sbi->s_chksum_driver)]; 1648 + } desc; 1649 + int err; 1650 + 1651 + desc.shash.tfm = sbi->s_chksum_driver; 1652 + desc.shash.flags = 0; 1653 + *(u32 *)desc.ctx = crc; 1654 + 1655 + err = crypto_shash_update(&desc.shash, address, length); 1656 + BUG_ON(err); 1657 + 1658 + return *(u32 *)desc.ctx; 1659 + } 1645 1660 1646 1661 #ifdef __KERNEL__ 1647 1662
+16
fs/ext4/super.c
··· 915 915 unlock_super(sb); 916 916 kobject_put(&sbi->s_kobj); 917 917 wait_for_completion(&sbi->s_kobj_unregister); 918 + if (sbi->s_chksum_driver) 919 + crypto_free_shash(sbi->s_chksum_driver); 918 920 kfree(sbi->s_blockgroup_lock); 919 921 kfree(sbi); 920 922 } ··· 3045 3043 goto cantfind_ext4; 3046 3044 } 3047 3045 3046 + /* Load the checksum driver */ 3047 + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, 3048 + EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) { 3049 + sbi->s_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); 3050 + if (IS_ERR(sbi->s_chksum_driver)) { 3051 + ext4_msg(sb, KERN_ERR, "Cannot load crc32c driver."); 3052 + ret = PTR_ERR(sbi->s_chksum_driver); 3053 + sbi->s_chksum_driver = NULL; 3054 + goto failed_mount; 3055 + } 3056 + } 3057 + 3048 3058 /* Set defaults before we parse the mount options */ 3049 3059 def_mount_opts = le32_to_cpu(es->s_default_mount_opts); 3050 3060 set_opt(sb, INIT_INODE_TABLE); ··· 3742 3728 brelse(sbi->s_group_desc[i]); 3743 3729 ext4_kvfree(sbi->s_group_desc); 3744 3730 failed_mount: 3731 + if (sbi->s_chksum_driver) 3732 + crypto_free_shash(sbi->s_chksum_driver); 3745 3733 if (sbi->s_proc) { 3746 3734 remove_proc_entry("options", sbi->s_proc); 3747 3735 remove_proc_entry(sb->s_id, ext4_proc_root);