Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e586fa0 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: fix crc endian conversion



While calculating CRC for the checkpoint block, we use __u32, but when storing
the crc value to the disk, we use __le32.

Let's fix the inconsistency.

Reported-and-Tested-by: default avatarOded Gabbay <ogabbay@advaoptical.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
parent 696c018c
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
	unsigned long blk_size = sbi->blocksize;
	struct f2fs_checkpoint *cp_block;
	unsigned long long cur_version = 0, pre_version = 0;
	unsigned int crc = 0;
	size_t crc_offset;
	__u32 crc = 0;

	/* Read the 1st cp block in this CP pack */
	cp_page_1 = get_meta_page(sbi, cp_addr);
@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
	if (crc_offset >= blk_size)
		goto invalid_cp1;

	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
	crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
	if (!f2fs_crc_valid(crc, cp_block, crc_offset))
		goto invalid_cp1;

@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
	if (crc_offset >= blk_size)
		goto invalid_cp2;

	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
	crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset)));
	if (!f2fs_crc_valid(crc, cp_block, crc_offset))
		goto invalid_cp2;

@@ -648,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
	block_t start_blk;
	struct page *cp_page;
	unsigned int data_sum_blocks, orphan_blocks;
	unsigned int crc32 = 0;
	__u32 crc32 = 0;
	void *kaddr;
	int i;

@@ -717,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
	get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));

	crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
	*(__le32 *)((unsigned char *)ckpt +
				le32_to_cpu(ckpt->checksum_offset))
	*((__le32 *)((unsigned char *)ckpt +
				le32_to_cpu(ckpt->checksum_offset)))
				= cpu_to_le32(crc32);

	start_blk = __start_cp_addr(sbi);
+15 −4
Original line number Diff line number Diff line
@@ -47,14 +47,25 @@ struct f2fs_mount_info {
	unsigned int	opt;
};

static inline __u32 f2fs_crc32(void *buff, size_t len)
#define CRCPOLY_LE 0xedb88320

static inline __u32 f2fs_crc32(void *buf, size_t len)
{
	return crc32_le(F2FS_SUPER_MAGIC, buff, 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 *buff, size_t buff_size)
static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size)
{
	return f2fs_crc32(buff, buff_size) == blk_crc;
	return f2fs_crc32(buf, buf_size) == blk_crc;
}

/*