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

jbd2: switch to using the crc32c library

Now that the crc32c() library function directly takes advantage of
architecture-specific optimizations, it is unnecessary to go through the
crypto API. Just use crc32c(). This is much simpler, and it improves
performance due to eliminating the crypto API overhead.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Acked-by: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20241202010844.144356-18-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>

+6 -59
-2
fs/jbd2/Kconfig
··· 2 2 config JBD2 3 3 tristate 4 4 select CRC32 5 - select CRYPTO 6 - select CRYPTO_CRC32C 7 5 help 8 6 This is a generic journaling layer for block devices that support 9 7 both 32-bit and 64-bit block numbers. It is currently used by
+3 -27
fs/jbd2/journal.c
··· 1369 1369 return err; 1370 1370 } 1371 1371 1372 - /* Load the checksum driver */ 1373 1372 if (jbd2_journal_has_csum_v2or3_feature(journal)) { 1374 1373 if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) { 1375 1374 printk(KERN_ERR "JBD2: Unknown checksum type\n"); 1376 1375 return err; 1377 1376 } 1378 1377 1379 - journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); 1380 - if (IS_ERR(journal->j_chksum_driver)) { 1381 - printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); 1382 - err = PTR_ERR(journal->j_chksum_driver); 1383 - journal->j_chksum_driver = NULL; 1384 - return err; 1385 - } 1386 1378 /* Check superblock checksum */ 1387 1379 if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) { 1388 1380 printk(KERN_ERR "JBD2: journal checksum error\n"); ··· 1600 1608 1601 1609 err_cleanup: 1602 1610 percpu_counter_destroy(&journal->j_checkpoint_jh_count); 1603 - if (journal->j_chksum_driver) 1604 - crypto_free_shash(journal->j_chksum_driver); 1605 1611 kfree(journal->j_wbuf); 1606 1612 jbd2_journal_destroy_revoke(journal); 1607 1613 journal_fail_superblock(journal); ··· 2181 2191 iput(journal->j_inode); 2182 2192 if (journal->j_revoke) 2183 2193 jbd2_journal_destroy_revoke(journal); 2184 - if (journal->j_chksum_driver) 2185 - crypto_free_shash(journal->j_chksum_driver); 2186 2194 kfree(journal->j_fc_wbuf); 2187 2195 kfree(journal->j_wbuf); 2188 2196 kfree(journal); ··· 2325 2337 } 2326 2338 } 2327 2339 2328 - /* Load the checksum driver if necessary */ 2329 - if ((journal->j_chksum_driver == NULL) && 2330 - INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { 2331 - journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0); 2332 - if (IS_ERR(journal->j_chksum_driver)) { 2333 - printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n"); 2334 - journal->j_chksum_driver = NULL; 2335 - return 0; 2336 - } 2337 - /* Precompute checksum seed for all metadata */ 2338 - journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, 2339 - sizeof(sb->s_uuid)); 2340 - } 2341 - 2342 2340 lock_buffer(journal->j_sb_buffer); 2343 2341 2344 - /* If enabling v3 checksums, update superblock */ 2342 + /* If enabling v3 checksums, update superblock and precompute seed */ 2345 2343 if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) { 2346 2344 sb->s_checksum_type = JBD2_CRC32C_CHKSUM; 2347 2345 sb->s_feature_compat &= 2348 2346 ~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); 2347 + journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid, 2348 + sizeof(sb->s_uuid)); 2349 2349 } 2350 2350 2351 2351 /* If enabling v1 checksums, downgrade superblock */
+3 -30
include/linux/jbd2.h
··· 28 28 #include <linux/slab.h> 29 29 #include <linux/bit_spinlock.h> 30 30 #include <linux/blkdev.h> 31 - #include <crypto/hash.h> 31 + #include <linux/crc32c.h> 32 32 #endif 33 33 34 34 #define journal_oom_retry 1 ··· 1242 1242 void *j_private; 1243 1243 1244 1244 /** 1245 - * @j_chksum_driver: 1246 - * 1247 - * Reference to checksum algorithm driver via cryptoapi. 1248 - */ 1249 - struct crypto_shash *j_chksum_driver; 1250 - 1251 - /** 1252 1245 * @j_csum_seed: 1253 1246 * 1254 1247 * Precomputed journal UUID checksum for seeding other checksums. ··· 1743 1750 1744 1751 static inline int jbd2_journal_has_csum_v2or3(journal_t *journal) 1745 1752 { 1746 - WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) && 1747 - journal->j_chksum_driver == NULL); 1748 - 1749 - return journal->j_chksum_driver != NULL; 1753 + return jbd2_journal_has_csum_v2or3_feature(journal); 1750 1754 } 1751 1755 1752 1756 static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb) ··· 1780 1790 #define BJ_Reserved 4 /* Buffer is reserved for access by journal */ 1781 1791 #define BJ_Types 5 1782 1792 1783 - /* JBD uses a CRC32 checksum */ 1784 - #define JBD_MAX_CHECKSUM_SIZE 4 1785 - 1786 1793 static inline u32 jbd2_chksum(journal_t *journal, u32 crc, 1787 1794 const void *address, unsigned int length) 1788 1795 { 1789 - DEFINE_RAW_FLEX(struct shash_desc, desc, __ctx, 1790 - DIV_ROUND_UP(JBD_MAX_CHECKSUM_SIZE, 1791 - sizeof(*((struct shash_desc *)0)->__ctx))); 1792 - int err; 1793 - 1794 - BUG_ON(crypto_shash_descsize(journal->j_chksum_driver) > 1795 - JBD_MAX_CHECKSUM_SIZE); 1796 - 1797 - desc->tfm = journal->j_chksum_driver; 1798 - *(u32 *)desc->__ctx = crc; 1799 - 1800 - err = crypto_shash_update(desc, address, length); 1801 - BUG_ON(err); 1802 - 1803 - return *(u32 *)desc->__ctx; 1796 + return crc32c(crc, address, length); 1804 1797 } 1805 1798 1806 1799 /* Return most recent uncommitted transaction */