Skip to content

Commit 54ab25d

Browse files
committed
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: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a78c5c2 commit 54ab25d

File tree

2 files changed

+13
-20
lines changed

2 files changed

+13
-20
lines changed

fs/erofs/erofs_fs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef __EROFS_FS_H
1010
#define __EROFS_FS_H
1111

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

1415
#define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001
@@ -54,7 +55,7 @@ struct erofs_deviceslot {
5455
/* erofs on-disk super block (currently 128 bytes) */
5556
struct erofs_super_block {
5657
__le32 magic; /* file system magic number */
57-
__le32 checksum; /* crc32c(super_block) */
58+
__le32 checksum; /* crc32c to avoid unexpected on-disk overlap */
5859
__le32 feature_compat;
5960
__u8 blkszbits; /* filesystem block size in bit shift */
6061
__u8 sb_extslots; /* superblock size = 128 + sb_extslots * 16 */

fs/erofs/super.c

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,21 @@ void _erofs_printk(struct super_block *sb, const char *fmt, ...)
3939

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

4645
if (len > EROFS_SUPER_OFFSET)
4746
len -= EROFS_SUPER_OFFSET;
47+
len -= offsetof(struct erofs_super_block, checksum) +
48+
sizeof(dsb->checksum);
4849

49-
dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, len, GFP_KERNEL);
50-
if (!dsb)
51-
return -ENOMEM;
52-
53-
expected_crc = le32_to_cpu(dsb->checksum);
54-
dsb->checksum = 0;
55-
/* to allow for x86 boot sectors and other oddities. */
56-
crc = crc32c(~0, dsb, len);
57-
kfree(dsb);
58-
59-
if (crc != expected_crc) {
60-
erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected",
61-
crc, expected_crc);
62-
return -EBADMSG;
63-
}
64-
return 0;
50+
/* skip .magic(pre-verified) and .checksum(0) fields */
51+
crc = crc32c(0x5045B54A, (&dsb->checksum) + 1, len);
52+
if (crc == le32_to_cpu(dsb->checksum))
53+
return 0;
54+
erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected",
55+
crc, le32_to_cpu(dsb->checksum));
56+
return -EBADMSG;
6557
}
6658

6759
static void erofs_inode_init_once(void *ptr)

0 commit comments

Comments
 (0)