f2fs: use cryptoapi crc32 functions
The crc function is done bit by bit. Optimize this by use cryptoapi crc32 function which is backed by h/w acceleration. Signed-off-by: Keith Mok <ek9852@gmail.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
999270de31
commit
43b6573bac
4 changed files with 45 additions and 24 deletions
|
@ -1,6 +1,8 @@
|
||||||
config F2FS_FS
|
config F2FS_FS
|
||||||
tristate "F2FS filesystem support"
|
tristate "F2FS filesystem support"
|
||||||
depends on BLOCK
|
depends on BLOCK
|
||||||
|
select CRYPTO
|
||||||
|
select CRYPTO_CRC32
|
||||||
help
|
help
|
||||||
F2FS is based on Log-structured File System (LFS), which supports
|
F2FS is based on Log-structured File System (LFS), which supports
|
||||||
versatile "flash-friendly" features. The design has been focused on
|
versatile "flash-friendly" features. The design has been focused on
|
||||||
|
|
|
@ -635,7 +635,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
|
||||||
goto invalid_cp1;
|
goto invalid_cp1;
|
||||||
|
|
||||||
crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset)));
|
crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset)));
|
||||||
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
|
if (!f2fs_crc_valid(sbi, crc, cp_block, crc_offset))
|
||||||
goto invalid_cp1;
|
goto invalid_cp1;
|
||||||
|
|
||||||
pre_version = cur_cp_version(cp_block);
|
pre_version = cur_cp_version(cp_block);
|
||||||
|
@ -650,7 +650,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
|
||||||
goto invalid_cp2;
|
goto invalid_cp2;
|
||||||
|
|
||||||
crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset)));
|
crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset)));
|
||||||
if (!f2fs_crc_valid(crc, cp_block, crc_offset))
|
if (!f2fs_crc_valid(sbi, crc, cp_block, crc_offset))
|
||||||
goto invalid_cp2;
|
goto invalid_cp2;
|
||||||
|
|
||||||
cur_version = cur_cp_version(cp_block);
|
cur_version = cur_cp_version(cp_block);
|
||||||
|
@ -1029,7 +1029,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
|
||||||
get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP));
|
get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP));
|
||||||
get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
|
get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
|
||||||
|
|
||||||
crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
|
crc32 = f2fs_crc32(sbi, ckpt, le32_to_cpu(ckpt->checksum_offset));
|
||||||
*((__le32 *)((unsigned char *)ckpt +
|
*((__le32 *)((unsigned char *)ckpt +
|
||||||
le32_to_cpu(ckpt->checksum_offset)))
|
le32_to_cpu(ckpt->checksum_offset)))
|
||||||
= cpu_to_le32(crc32);
|
= cpu_to_le32(crc32);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/fscrypto.h>
|
#include <linux/fscrypto.h>
|
||||||
|
#include <crypto/hash.h>
|
||||||
|
|
||||||
#ifdef CONFIG_F2FS_CHECK_FS
|
#ifdef CONFIG_F2FS_CHECK_FS
|
||||||
#define f2fs_bug_on(sbi, condition) BUG_ON(condition)
|
#define f2fs_bug_on(sbi, condition) BUG_ON(condition)
|
||||||
|
@ -83,27 +84,6 @@ struct f2fs_mount_info {
|
||||||
#define F2FS_CLEAR_FEATURE(sb, mask) \
|
#define F2FS_CLEAR_FEATURE(sb, mask) \
|
||||||
F2FS_SB(sb)->raw_super->feature &= ~cpu_to_le32(mask)
|
F2FS_SB(sb)->raw_super->feature &= ~cpu_to_le32(mask)
|
||||||
|
|
||||||
#define CRCPOLY_LE 0xedb88320
|
|
||||||
|
|
||||||
static inline __u32 f2fs_crc32(void *buf, size_t len)
|
|
||||||
{
|
|
||||||
unsigned char *p = (unsigned char *)buf;
|
|
||||||
__u32 crc = F2FS_SUPER_MAGIC;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while (len--) {
|
|
||||||
crc ^= *p++;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size)
|
|
||||||
{
|
|
||||||
return f2fs_crc32(buf, buf_size) == blk_crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For checkpoint manager
|
* For checkpoint manager
|
||||||
*/
|
*/
|
||||||
|
@ -819,6 +799,9 @@ struct f2fs_sb_info {
|
||||||
/* For write statistics */
|
/* For write statistics */
|
||||||
u64 sectors_written_start;
|
u64 sectors_written_start;
|
||||||
u64 kbytes_written;
|
u64 kbytes_written;
|
||||||
|
|
||||||
|
/* Reference to checksum algorithm driver via cryptoapi */
|
||||||
|
struct crypto_shash *s_chksum_driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For write statistics. Suppose sector size is 512 bytes,
|
/* For write statistics. Suppose sector size is 512 bytes,
|
||||||
|
@ -856,6 +839,29 @@ static inline bool is_idle(struct f2fs_sb_info *sbi)
|
||||||
/*
|
/*
|
||||||
* Inline functions
|
* Inline functions
|
||||||
*/
|
*/
|
||||||
|
static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address,
|
||||||
|
unsigned int length)
|
||||||
|
{
|
||||||
|
SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver);
|
||||||
|
u32 *ctx = (u32 *)shash_desc_ctx(shash);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
shash->tfm = sbi->s_chksum_driver;
|
||||||
|
shash->flags = 0;
|
||||||
|
*ctx = F2FS_SUPER_MAGIC;
|
||||||
|
|
||||||
|
err = crypto_shash_update(shash, address, length);
|
||||||
|
BUG_ON(err);
|
||||||
|
|
||||||
|
return *ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
|
||||||
|
void *buf, size_t buf_size)
|
||||||
|
{
|
||||||
|
return f2fs_crc32(sbi, buf, buf_size) == blk_crc;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct f2fs_inode_info *F2FS_I(struct inode *inode)
|
static inline struct f2fs_inode_info *F2FS_I(struct inode *inode)
|
||||||
{
|
{
|
||||||
return container_of(inode, struct f2fs_inode_info, vfs_inode);
|
return container_of(inode, struct f2fs_inode_info, vfs_inode);
|
||||||
|
|
|
@ -590,6 +590,8 @@ static void f2fs_put_super(struct super_block *sb)
|
||||||
wait_for_completion(&sbi->s_kobj_unregister);
|
wait_for_completion(&sbi->s_kobj_unregister);
|
||||||
|
|
||||||
sb->s_fs_info = NULL;
|
sb->s_fs_info = NULL;
|
||||||
|
if (sbi->s_chksum_driver)
|
||||||
|
crypto_free_shash(sbi->s_chksum_driver);
|
||||||
kfree(sbi->raw_super);
|
kfree(sbi->raw_super);
|
||||||
kfree(sbi);
|
kfree(sbi);
|
||||||
}
|
}
|
||||||
|
@ -1310,6 +1312,15 @@ try_onemore:
|
||||||
if (!sbi)
|
if (!sbi)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Load the checksum driver */
|
||||||
|
sbi->s_chksum_driver = crypto_alloc_shash("crc32", 0, 0);
|
||||||
|
if (IS_ERR(sbi->s_chksum_driver)) {
|
||||||
|
f2fs_msg(sb, KERN_ERR, "Cannot load crc32 driver.");
|
||||||
|
err = PTR_ERR(sbi->s_chksum_driver);
|
||||||
|
sbi->s_chksum_driver = NULL;
|
||||||
|
goto free_sbi;
|
||||||
|
}
|
||||||
|
|
||||||
/* set a block size */
|
/* set a block size */
|
||||||
if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) {
|
if (unlikely(!sb_set_blocksize(sb, F2FS_BLKSIZE))) {
|
||||||
f2fs_msg(sb, KERN_ERR, "unable to set blocksize");
|
f2fs_msg(sb, KERN_ERR, "unable to set blocksize");
|
||||||
|
@ -1568,6 +1579,8 @@ free_options:
|
||||||
free_sb_buf:
|
free_sb_buf:
|
||||||
kfree(raw_super);
|
kfree(raw_super);
|
||||||
free_sbi:
|
free_sbi:
|
||||||
|
if (sbi->s_chksum_driver)
|
||||||
|
crypto_free_shash(sbi->s_chksum_driver);
|
||||||
kfree(sbi);
|
kfree(sbi);
|
||||||
|
|
||||||
/* give only one another chance */
|
/* give only one another chance */
|
||||||
|
|
Loading…
Add table
Reference in a new issue