mirror of https://github.com/torvalds/linux.git
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>
This commit is contained in:
parent
f2b4fa1964
commit
dd348f054b
|
|
@ -2,8 +2,6 @@
|
||||||
config JBD2
|
config JBD2
|
||||||
tristate
|
tristate
|
||||||
select CRC32
|
select CRC32
|
||||||
select CRYPTO
|
|
||||||
select CRYPTO_CRC32C
|
|
||||||
help
|
help
|
||||||
This is a generic journaling layer for block devices that support
|
This is a generic journaling layer for block devices that support
|
||||||
both 32-bit and 64-bit block numbers. It is currently used by
|
both 32-bit and 64-bit block numbers. It is currently used by
|
||||||
|
|
|
||||||
|
|
@ -1369,20 +1369,12 @@ static int journal_check_superblock(journal_t *journal)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the checksum driver */
|
|
||||||
if (jbd2_journal_has_csum_v2or3_feature(journal)) {
|
if (jbd2_journal_has_csum_v2or3_feature(journal)) {
|
||||||
if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) {
|
if (sb->s_checksum_type != JBD2_CRC32C_CHKSUM) {
|
||||||
printk(KERN_ERR "JBD2: Unknown checksum type\n");
|
printk(KERN_ERR "JBD2: Unknown checksum type\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
|
|
||||||
if (IS_ERR(journal->j_chksum_driver)) {
|
|
||||||
printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
|
|
||||||
err = PTR_ERR(journal->j_chksum_driver);
|
|
||||||
journal->j_chksum_driver = NULL;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
/* Check superblock checksum */
|
/* Check superblock checksum */
|
||||||
if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) {
|
if (sb->s_checksum != jbd2_superblock_csum(journal, sb)) {
|
||||||
printk(KERN_ERR "JBD2: journal checksum error\n");
|
printk(KERN_ERR "JBD2: journal checksum error\n");
|
||||||
|
|
@ -1608,8 +1600,6 @@ static journal_t *journal_init_common(struct block_device *bdev,
|
||||||
|
|
||||||
err_cleanup:
|
err_cleanup:
|
||||||
percpu_counter_destroy(&journal->j_checkpoint_jh_count);
|
percpu_counter_destroy(&journal->j_checkpoint_jh_count);
|
||||||
if (journal->j_chksum_driver)
|
|
||||||
crypto_free_shash(journal->j_chksum_driver);
|
|
||||||
kfree(journal->j_wbuf);
|
kfree(journal->j_wbuf);
|
||||||
jbd2_journal_destroy_revoke(journal);
|
jbd2_journal_destroy_revoke(journal);
|
||||||
journal_fail_superblock(journal);
|
journal_fail_superblock(journal);
|
||||||
|
|
@ -2191,8 +2181,6 @@ int jbd2_journal_destroy(journal_t *journal)
|
||||||
iput(journal->j_inode);
|
iput(journal->j_inode);
|
||||||
if (journal->j_revoke)
|
if (journal->j_revoke)
|
||||||
jbd2_journal_destroy_revoke(journal);
|
jbd2_journal_destroy_revoke(journal);
|
||||||
if (journal->j_chksum_driver)
|
|
||||||
crypto_free_shash(journal->j_chksum_driver);
|
|
||||||
kfree(journal->j_fc_wbuf);
|
kfree(journal->j_fc_wbuf);
|
||||||
kfree(journal->j_wbuf);
|
kfree(journal->j_wbuf);
|
||||||
kfree(journal);
|
kfree(journal);
|
||||||
|
|
@ -2337,27 +2325,15 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the checksum driver if necessary */
|
|
||||||
if ((journal->j_chksum_driver == NULL) &&
|
|
||||||
INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
|
|
||||||
journal->j_chksum_driver = crypto_alloc_shash("crc32c", 0, 0);
|
|
||||||
if (IS_ERR(journal->j_chksum_driver)) {
|
|
||||||
printk(KERN_ERR "JBD2: Cannot load crc32c driver.\n");
|
|
||||||
journal->j_chksum_driver = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Precompute checksum seed for all metadata */
|
|
||||||
journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
|
|
||||||
sizeof(sb->s_uuid));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock_buffer(journal->j_sb_buffer);
|
lock_buffer(journal->j_sb_buffer);
|
||||||
|
|
||||||
/* If enabling v3 checksums, update superblock */
|
/* If enabling v3 checksums, update superblock and precompute seed */
|
||||||
if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
|
if (INCOMPAT_FEATURE_ON(JBD2_FEATURE_INCOMPAT_CSUM_V3)) {
|
||||||
sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
|
sb->s_checksum_type = JBD2_CRC32C_CHKSUM;
|
||||||
sb->s_feature_compat &=
|
sb->s_feature_compat &=
|
||||||
~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
|
~cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
|
||||||
|
journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
|
||||||
|
sizeof(sb->s_uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If enabling v1 checksums, downgrade superblock */
|
/* If enabling v1 checksums, downgrade superblock */
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/bit_spinlock.h>
|
#include <linux/bit_spinlock.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <crypto/hash.h>
|
#include <linux/crc32c.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define journal_oom_retry 1
|
#define journal_oom_retry 1
|
||||||
|
|
@ -1241,13 +1241,6 @@ struct journal_s
|
||||||
*/
|
*/
|
||||||
void *j_private;
|
void *j_private;
|
||||||
|
|
||||||
/**
|
|
||||||
* @j_chksum_driver:
|
|
||||||
*
|
|
||||||
* Reference to checksum algorithm driver via cryptoapi.
|
|
||||||
*/
|
|
||||||
struct crypto_shash *j_chksum_driver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @j_csum_seed:
|
* @j_csum_seed:
|
||||||
*
|
*
|
||||||
|
|
@ -1750,10 +1743,7 @@ static inline bool jbd2_journal_has_csum_v2or3_feature(journal_t *j)
|
||||||
|
|
||||||
static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
|
static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
|
||||||
{
|
{
|
||||||
WARN_ON_ONCE(jbd2_journal_has_csum_v2or3_feature(journal) &&
|
return jbd2_journal_has_csum_v2or3_feature(journal);
|
||||||
journal->j_chksum_driver == NULL);
|
|
||||||
|
|
||||||
return journal->j_chksum_driver != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
|
static inline int jbd2_journal_get_num_fc_blks(journal_superblock_t *jsb)
|
||||||
|
|
@ -1790,27 +1780,10 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal)
|
||||||
#define BJ_Reserved 4 /* Buffer is reserved for access by journal */
|
#define BJ_Reserved 4 /* Buffer is reserved for access by journal */
|
||||||
#define BJ_Types 5
|
#define BJ_Types 5
|
||||||
|
|
||||||
/* JBD uses a CRC32 checksum */
|
|
||||||
#define JBD_MAX_CHECKSUM_SIZE 4
|
|
||||||
|
|
||||||
static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
|
static inline u32 jbd2_chksum(journal_t *journal, u32 crc,
|
||||||
const void *address, unsigned int length)
|
const void *address, unsigned int length)
|
||||||
{
|
{
|
||||||
DEFINE_RAW_FLEX(struct shash_desc, desc, __ctx,
|
return crc32c(crc, address, length);
|
||||||
DIV_ROUND_UP(JBD_MAX_CHECKSUM_SIZE,
|
|
||||||
sizeof(*((struct shash_desc *)0)->__ctx)));
|
|
||||||
int err;
|
|
||||||
|
|
||||||
BUG_ON(crypto_shash_descsize(journal->j_chksum_driver) >
|
|
||||||
JBD_MAX_CHECKSUM_SIZE);
|
|
||||||
|
|
||||||
desc->tfm = journal->j_chksum_driver;
|
|
||||||
*(u32 *)desc->__ctx = crc;
|
|
||||||
|
|
||||||
err = crypto_shash_update(desc, address, length);
|
|
||||||
BUG_ON(err);
|
|
||||||
|
|
||||||
return *(u32 *)desc->__ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return most recent uncommitted transaction */
|
/* Return most recent uncommitted transaction */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue