Commit 54ab25d0 authored by Gao Xiang's avatar Gao Xiang
Browse files

erofs: micro-optimize superblock checksum



Just verify the remaining unknown on-disk data instead of allocating a
temporary buffer for the whole superblock and zeroing out the checksum
field since .magic(EROFS_SUPER_MAGIC_V1) is verified and .checksum(0)
is fixed.

Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20241212023948.1143038-1-hsiangkao@linux.alibaba.com
parent a78c5c22
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#ifndef __EROFS_FS_H
#define __EROFS_FS_H

/* to allow for x86 boot sectors and other oddities. */
#define EROFS_SUPER_OFFSET      1024

#define EROFS_FEATURE_COMPAT_SB_CHKSUM          0x00000001
@@ -54,7 +55,7 @@ struct erofs_deviceslot {
/* erofs on-disk super block (currently 128 bytes) */
struct erofs_super_block {
	__le32 magic;           /* file system magic number */
	__le32 checksum;        /* crc32c(super_block) */
	__le32 checksum;        /* crc32c to avoid unexpected on-disk overlap */
	__le32 feature_compat;
	__u8 blkszbits;         /* filesystem block size in bit shift */
	__u8 sb_extslots;	/* superblock size = 128 + sb_extslots * 16 */
+11 −19
Original line number Diff line number Diff line
@@ -39,30 +39,22 @@ void _erofs_printk(struct super_block *sb, const char *fmt, ...)

static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
{
	size_t len = 1 << EROFS_SB(sb)->blkszbits;
	struct erofs_super_block *dsb;
	u32 expected_crc, crc;
	struct erofs_super_block *dsb = sbdata + EROFS_SUPER_OFFSET;
	u32 len = 1 << EROFS_SB(sb)->blkszbits, crc;

	if (len > EROFS_SUPER_OFFSET)
		len -= EROFS_SUPER_OFFSET;
	len -= offsetof(struct erofs_super_block, checksum) +
			sizeof(dsb->checksum);

	dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, len, GFP_KERNEL);
	if (!dsb)
		return -ENOMEM;

	expected_crc = le32_to_cpu(dsb->checksum);
	dsb->checksum = 0;
	/* to allow for x86 boot sectors and other oddities. */
	crc = crc32c(~0, dsb, len);
	kfree(dsb);

	if (crc != expected_crc) {
	/* skip .magic(pre-verified) and .checksum(0) fields */
	crc = crc32c(0x5045B54A, (&dsb->checksum) + 1, len);
	if (crc == le32_to_cpu(dsb->checksum))
		return 0;
	erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected",
			  crc, expected_crc);
		  crc, le32_to_cpu(dsb->checksum));
	return -EBADMSG;
}
	return 0;
}

static void erofs_inode_init_once(void *ptr)
{