History

f2fs: allow unfixed f2fs_checkpoint.checksum_offset

Previously, f2fs_checkpoint.checksum_offset points fixed position of f2fs_checkpoint structure: "#define CP_CHKSUM_OFFSET 4092" It is unnecessary, and it breaks the consecutiveness of nat and sit bitmap stored across checkpoint park block and payload blocks. This patch allows f2fs to handle unfixed .checksum_offset. In addition, for the case checksum value is stored in the middle of checkpoint park, calculating checksum value with superposition method like we did for inode_checksum.

Chao Yu committed 7 years ago

Commit d7eb8f11 parent 3a912b72 files · +25 −6Browse files

Unified · Split

2 files
  1. fs/f2fs/checkpoint.c +21 −6
  2. include/linux/f2fs_fs.h +4 −0
fs/f2fs/checkpoint.c+21−6
@@ -758,13 +758,27 @@ static void write_orphan_inodes(struct f2fs_sb_info *sbi, block_t start_blk) · 757 unmodified lines
758758 }
759759 }
760760
761+static __u32 f2fs_checkpoint_chksum(struct f2fs_sb_info *sbi,
762+ struct f2fs_checkpoint *ckpt)
763+{
764+ unsigned int chksum_ofs = le32_to_cpu(ckpt->checksum_offset);
765+ __u32 chksum;
766+
767+ chksum = f2fs_crc32(sbi, ckpt, chksum_ofs);
768+ if (chksum_ofs < CP_CHKSUM_OFFSET) {
769+ chksum_ofs += sizeof(chksum);
770+ chksum = f2fs_chksum(sbi, chksum, (__u8 *)ckpt + chksum_ofs,
771+ F2FS_BLKSIZE - chksum_ofs);
772+ }
773+ return chksum;
774+}
775+
761776 static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr,
762777 struct f2fs_checkpoint **cp_block, struct page **cp_page,
763778 unsigned long long *version)
764779 {
765− unsigned long blk_size = sbi->blocksize;
766780 size_t crc_offset = 0;
767− __u32 crc = 0;
781+ __u32 crc;
768782
769783 *cp_page = f2fs_get_meta_page(sbi, cp_addr);
770784 if (IS_ERR(*cp_page))
@@ -773,15 +787,16 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, · 2 unmodified lines
773787 *cp_block = (struct f2fs_checkpoint *)page_address(*cp_page);
774788
775789 crc_offset = le32_to_cpu((*cp_block)->checksum_offset);
776− if (crc_offset > (blk_size - sizeof(__le32))) {
790+ if (crc_offset < CP_MIN_CHKSUM_OFFSET ||
791+ crc_offset > CP_CHKSUM_OFFSET) {
777792 f2fs_put_page(*cp_page, 1);
778793 f2fs_msg(sbi->sb, KERN_WARNING,
779794 "invalid crc_offset: %zu", crc_offset);
780795 return -EINVAL;
781796 }
782797
783− crc = cur_cp_crc(*cp_block);
784− if (!f2fs_crc_valid(sbi, crc, *cp_block, crc_offset)) {
798+ crc = f2fs_checkpoint_chksum(sbi, *cp_block);
799+ if (crc != cur_cp_crc(*cp_block)) {
785800 f2fs_put_page(*cp_page, 1);
786801 f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value");
787802 return -EINVAL;
@@ -1389,7 +1404,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) · 601 unmodified lines
13891404 get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP));
13901405 get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
13911406
1392− crc32 = f2fs_crc32(sbi, ckpt, le32_to_cpu(ckpt->checksum_offset));
1407+ crc32 = f2fs_checkpoint_chksum(sbi, ckpt);
13931408 *((__le32 *)((unsigned char *)ckpt +
13941409 le32_to_cpu(ckpt->checksum_offset)))
13951410 = cpu_to_le32(crc32);
include/linux/f2fs_fs.h+4−0
@@ -164,6 +164,10 @@ struct f2fs_checkpoint { · 163 unmodified lines
164164 unsigned char sit_nat_version_bitmap[1];
165165 } __packed;
166166
167+#define CP_CHKSUM_OFFSET 4092 /* default chksum offset in checkpoint */
168+#define CP_MIN_CHKSUM_OFFSET \
169+ (offsetof(struct f2fs_checkpoint, sit_nat_version_bitmap))
170+
167171 /*
168172 * For orphan inode management
169173 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t