|
@@ -371,7 +371,9 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi)
|
|
|
return;
|
|
|
|
|
|
sbi->por_doing = true;
|
|
|
- start_blk = __start_cp_addr(sbi) + 1;
|
|
|
+
|
|
|
+ start_blk = __start_cp_addr(sbi) + 1 +
|
|
|
+ le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
|
|
|
orphan_blkaddr = __start_sum_addr(sbi) - 1;
|
|
|
|
|
|
ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
|
|
@@ -512,8 +514,11 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
|
|
|
unsigned long blk_size = sbi->blocksize;
|
|
|
unsigned long long cp1_version = 0, cp2_version = 0;
|
|
|
unsigned long long cp_start_blk_no;
|
|
|
+ unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
|
|
|
+ block_t cp_blk_no;
|
|
|
+ int i;
|
|
|
|
|
|
- sbi->ckpt = kzalloc(blk_size, GFP_KERNEL);
|
|
|
+ sbi->ckpt = kzalloc(cp_blks * blk_size, GFP_KERNEL);
|
|
|
if (!sbi->ckpt)
|
|
|
return -ENOMEM;
|
|
|
/*
|
|
@@ -544,6 +549,23 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
|
|
|
cp_block = (struct f2fs_checkpoint *)page_address(cur_page);
|
|
|
memcpy(sbi->ckpt, cp_block, blk_size);
|
|
|
|
|
|
+ if (cp_blks <= 1)
|
|
|
+ goto done;
|
|
|
+
|
|
|
+ cp_blk_no = le32_to_cpu(fsb->cp_blkaddr);
|
|
|
+ if (cur_page == cp2)
|
|
|
+ cp_blk_no += 1 << le32_to_cpu(fsb->log_blocks_per_seg);
|
|
|
+
|
|
|
+ for (i = 1; i < cp_blks; i++) {
|
|
|
+ void *sit_bitmap_ptr;
|
|
|
+ unsigned char *ckpt = (unsigned char *)sbi->ckpt;
|
|
|
+
|
|
|
+ cur_page = get_meta_page(sbi, cp_blk_no + i);
|
|
|
+ sit_bitmap_ptr = page_address(cur_page);
|
|
|
+ memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size);
|
|
|
+ f2fs_put_page(cur_page, 1);
|
|
|
+ }
|
|
|
+done:
|
|
|
f2fs_put_page(cp1, 1);
|
|
|
f2fs_put_page(cp2, 1);
|
|
|
return 0;
|
|
@@ -736,6 +758,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
|
|
__u32 crc32 = 0;
|
|
|
void *kaddr;
|
|
|
int i;
|
|
|
+ int cp_payload_blks = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
|
|
|
|
|
|
/*
|
|
|
* This avoids to conduct wrong roll-forward operations and uses
|
|
@@ -786,16 +809,19 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
|
|
|
|
|
orphan_blocks = (sbi->n_orphans + F2FS_ORPHANS_PER_BLOCK - 1)
|
|
|
/ F2FS_ORPHANS_PER_BLOCK;
|
|
|
- ckpt->cp_pack_start_sum = cpu_to_le32(1 + orphan_blocks);
|
|
|
+ ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks +
|
|
|
+ orphan_blocks);
|
|
|
|
|
|
if (is_umount) {
|
|
|
set_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
|
|
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
|
|
- data_sum_blocks + orphan_blocks + NR_CURSEG_NODE_TYPE);
|
|
|
+ cp_payload_blks + data_sum_blocks +
|
|
|
+ orphan_blocks + NR_CURSEG_NODE_TYPE);
|
|
|
} else {
|
|
|
clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG);
|
|
|
ckpt->cp_pack_total_block_count = cpu_to_le32(2 +
|
|
|
- data_sum_blocks + orphan_blocks);
|
|
|
+ cp_payload_blks + data_sum_blocks +
|
|
|
+ orphan_blocks);
|
|
|
}
|
|
|
|
|
|
if (sbi->n_orphans)
|
|
@@ -821,6 +847,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
|
|
|
set_page_dirty(cp_page);
|
|
|
f2fs_put_page(cp_page, 1);
|
|
|
|
|
|
+ for (i = 1; i < 1 + cp_payload_blks; i++) {
|
|
|
+ cp_page = grab_meta_page(sbi, start_blk++);
|
|
|
+ kaddr = page_address(cp_page);
|
|
|
+ memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE,
|
|
|
+ (1 << sbi->log_blocksize));
|
|
|
+ set_page_dirty(cp_page);
|
|
|
+ f2fs_put_page(cp_page, 1);
|
|
|
+ }
|
|
|
+
|
|
|
if (sbi->n_orphans) {
|
|
|
write_orphan_inodes(sbi, start_blk);
|
|
|
start_blk += orphan_blocks;
|