diff options
author | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-06-19 07:47:19 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2013-07-01 19:47:35 -0400 |
commit | 7e586fa0244578320fcced9cc08c6b124f727c35 (patch) | |
tree | fb95e07a67d211f84d8722b4240c4c826822c4df /fs/f2fs | |
parent | 696c018c7718f5e33e1107da19c4d64a25018878 (diff) |
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: Oded Gabbay <ogabbay@advaoptical.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/checkpoint.c | 12 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 19 |
2 files changed, 21 insertions, 10 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 9a7750909221..66a6b85a51d8 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
357 | unsigned long blk_size = sbi->blocksize; | 357 | unsigned long blk_size = sbi->blocksize; |
358 | struct f2fs_checkpoint *cp_block; | 358 | struct f2fs_checkpoint *cp_block; |
359 | unsigned long long cur_version = 0, pre_version = 0; | 359 | unsigned long long cur_version = 0, pre_version = 0; |
360 | unsigned int crc = 0; | ||
361 | size_t crc_offset; | 360 | size_t crc_offset; |
361 | __u32 crc = 0; | ||
362 | 362 | ||
363 | /* Read the 1st cp block in this CP pack */ | 363 | /* Read the 1st cp block in this CP pack */ |
364 | cp_page_1 = get_meta_page(sbi, cp_addr); | 364 | cp_page_1 = get_meta_page(sbi, cp_addr); |
@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
369 | if (crc_offset >= blk_size) | 369 | if (crc_offset >= blk_size) |
370 | goto invalid_cp1; | 370 | goto invalid_cp1; |
371 | 371 | ||
372 | crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); | 372 | crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); |
373 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) | 373 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) |
374 | goto invalid_cp1; | 374 | goto invalid_cp1; |
375 | 375 | ||
@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
384 | if (crc_offset >= blk_size) | 384 | if (crc_offset >= blk_size) |
385 | goto invalid_cp2; | 385 | goto invalid_cp2; |
386 | 386 | ||
387 | crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); | 387 | crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); |
388 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) | 388 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) |
389 | goto invalid_cp2; | 389 | goto invalid_cp2; |
390 | 390 | ||
@@ -648,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
648 | block_t start_blk; | 648 | block_t start_blk; |
649 | struct page *cp_page; | 649 | struct page *cp_page; |
650 | unsigned int data_sum_blocks, orphan_blocks; | 650 | unsigned int data_sum_blocks, orphan_blocks; |
651 | unsigned int crc32 = 0; | 651 | __u32 crc32 = 0; |
652 | void *kaddr; | 652 | void *kaddr; |
653 | int i; | 653 | int i; |
654 | 654 | ||
@@ -717,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
717 | get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); | 717 | get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); |
718 | 718 | ||
719 | crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); | 719 | crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); |
720 | *(__le32 *)((unsigned char *)ckpt + | 720 | *((__le32 *)((unsigned char *)ckpt + |
721 | le32_to_cpu(ckpt->checksum_offset)) | 721 | le32_to_cpu(ckpt->checksum_offset))) |
722 | = cpu_to_le32(crc32); | 722 | = cpu_to_le32(crc32); |
723 | 723 | ||
724 | start_blk = __start_cp_addr(sbi); | 724 | start_blk = __start_cp_addr(sbi); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 863a5e91d84a..467d42d65c48 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -47,14 +47,25 @@ struct f2fs_mount_info { | |||
47 | unsigned int opt; | 47 | unsigned int opt; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static inline __u32 f2fs_crc32(void *buff, size_t len) | 50 | #define CRCPOLY_LE 0xedb88320 |
51 | |||
52 | static inline __u32 f2fs_crc32(void *buf, size_t len) | ||
51 | { | 53 | { |
52 | return crc32_le(F2FS_SUPER_MAGIC, buff, len); | 54 | unsigned char *p = (unsigned char *)buf; |
55 | __u32 crc = F2FS_SUPER_MAGIC; | ||
56 | int i; | ||
57 | |||
58 | while (len--) { | ||
59 | crc ^= *p++; | ||
60 | for (i = 0; i < 8; i++) | ||
61 | crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0); | ||
62 | } | ||
63 | return crc; | ||
53 | } | 64 | } |
54 | 65 | ||
55 | static inline bool f2fs_crc_valid(__u32 blk_crc, void *buff, size_t buff_size) | 66 | static inline bool f2fs_crc_valid(__u32 blk_crc, void *buf, size_t buf_size) |
56 | { | 67 | { |
57 | return f2fs_crc32(buff, buff_size) == blk_crc; | 68 | return f2fs_crc32(buf, buf_size) == blk_crc; |
58 | } | 69 | } |
59 | 70 | ||
60 | /* | 71 | /* |