diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-11-24 15:45:15 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-06 04:40:14 -0500 |
commit | 01e15b3328c4dc2073bc5080f1b31f21370be3f8 (patch) | |
tree | 770842560041703864d96729f8f33a0d8473ce23 /fs | |
parent | 027611ef345d118310c1334b5d25b27ff95da684 (diff) |
f2fs: fix to determine start_cp_addr by sbi->cur_cp_pack
commit 8508e44ae98622f841f5ef29d0bf3d5db4e0c1cc upstream.
We don't guarantee cp_addr is fixed by cp_version.
This is to sync with f2fs-tools.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/f2fs/checkpoint.c | 8 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 26 |
2 files changed, 23 insertions, 11 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 7e9b504bd8b2..b4dbc2f59656 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -772,6 +772,11 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
772 | if (sanity_check_ckpt(sbi)) | 772 | if (sanity_check_ckpt(sbi)) |
773 | goto fail_no_cp; | 773 | goto fail_no_cp; |
774 | 774 | ||
775 | if (cur_page == cp1) | ||
776 | sbi->cur_cp_pack = 1; | ||
777 | else | ||
778 | sbi->cur_cp_pack = 2; | ||
779 | |||
775 | if (cp_blks <= 1) | 780 | if (cp_blks <= 1) |
776 | goto done; | 781 | goto done; |
777 | 782 | ||
@@ -1123,7 +1128,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1123 | le32_to_cpu(ckpt->checksum_offset))) | 1128 | le32_to_cpu(ckpt->checksum_offset))) |
1124 | = cpu_to_le32(crc32); | 1129 | = cpu_to_le32(crc32); |
1125 | 1130 | ||
1126 | start_blk = __start_cp_addr(sbi); | 1131 | start_blk = __start_cp_next_addr(sbi); |
1127 | 1132 | ||
1128 | /* need to wait for end_io results */ | 1133 | /* need to wait for end_io results */ |
1129 | wait_on_all_pages_writeback(sbi); | 1134 | wait_on_all_pages_writeback(sbi); |
@@ -1187,6 +1192,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1187 | clear_prefree_segments(sbi, cpc); | 1192 | clear_prefree_segments(sbi, cpc); |
1188 | clear_sbi_flag(sbi, SBI_IS_DIRTY); | 1193 | clear_sbi_flag(sbi, SBI_IS_DIRTY); |
1189 | clear_sbi_flag(sbi, SBI_NEED_CP); | 1194 | clear_sbi_flag(sbi, SBI_NEED_CP); |
1195 | __set_cp_next_pack(sbi); | ||
1190 | 1196 | ||
1191 | /* | 1197 | /* |
1192 | * redirty superblock if metadata like node page or inode cache is | 1198 | * redirty superblock if metadata like node page or inode cache is |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 830c51b36089..6dd03115789b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -764,6 +764,7 @@ struct f2fs_sb_info { | |||
764 | 764 | ||
765 | /* for checkpoint */ | 765 | /* for checkpoint */ |
766 | struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ | 766 | struct f2fs_checkpoint *ckpt; /* raw checkpoint pointer */ |
767 | int cur_cp_pack; /* remain current cp pack */ | ||
767 | spinlock_t cp_lock; /* for flag in ckpt */ | 768 | spinlock_t cp_lock; /* for flag in ckpt */ |
768 | struct inode *meta_inode; /* cache meta blocks */ | 769 | struct inode *meta_inode; /* cache meta blocks */ |
769 | struct mutex cp_mutex; /* checkpoint procedure lock */ | 770 | struct mutex cp_mutex; /* checkpoint procedure lock */ |
@@ -1329,22 +1330,27 @@ static inline void *__bitmap_ptr(struct f2fs_sb_info *sbi, int flag) | |||
1329 | 1330 | ||
1330 | static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) | 1331 | static inline block_t __start_cp_addr(struct f2fs_sb_info *sbi) |
1331 | { | 1332 | { |
1332 | block_t start_addr; | 1333 | block_t start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr); |
1333 | struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); | ||
1334 | unsigned long long ckpt_version = cur_cp_version(ckpt); | ||
1335 | |||
1336 | start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr); | ||
1337 | 1334 | ||
1338 | /* | 1335 | if (sbi->cur_cp_pack == 2) |
1339 | * odd numbered checkpoint should at cp segment 0 | ||
1340 | * and even segment must be at cp segment 1 | ||
1341 | */ | ||
1342 | if (!(ckpt_version & 1)) | ||
1343 | start_addr += sbi->blocks_per_seg; | 1336 | start_addr += sbi->blocks_per_seg; |
1337 | return start_addr; | ||
1338 | } | ||
1344 | 1339 | ||
1340 | static inline block_t __start_cp_next_addr(struct f2fs_sb_info *sbi) | ||
1341 | { | ||
1342 | block_t start_addr = le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_blkaddr); | ||
1343 | |||
1344 | if (sbi->cur_cp_pack == 1) | ||
1345 | start_addr += sbi->blocks_per_seg; | ||
1345 | return start_addr; | 1346 | return start_addr; |
1346 | } | 1347 | } |
1347 | 1348 | ||
1349 | static inline void __set_cp_next_pack(struct f2fs_sb_info *sbi) | ||
1350 | { | ||
1351 | sbi->cur_cp_pack = (sbi->cur_cp_pack == 1) ? 2 : 1; | ||
1352 | } | ||
1353 | |||
1348 | static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi) | 1354 | static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi) |
1349 | { | 1355 | { |
1350 | return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum); | 1356 | return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum); |