aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>2019-11-28 16:59:27 +0900
committerJaegeuk Kim <jaegeuk@kernel.org>2019-12-09 17:23:19 -0800
commit7f6b9400147e69e7c523ab7a5efbf444aecbf8f5 (patch)
tree86bf1dc7059dd8decd51f824372e1f8dfceac8de
parentc0ce8e646c5c5454b74863496e0d0e6a66d7438f (diff)
downloadf2fs-tools-7f6b9400147e69e7c523ab7a5efbf444aecbf8f5.tar.gz
fsck: Introduce move_one_curseg_info() function
When fsck updates one of the current segments, update_curseg_info() is called specifying a single current segment as its argument. However, update_curseg_info() calls move_curseg_info() function which updates all six current segments. Then update_curseg_info() for a single current segment moves all current segments. This excessive current segment move causes an issue when a new zone is assigned to a current segment because of write pointer inconsistency. Even when a current segment has write pointer inconsistency, all other current segments should not be moved because they may have fsync data at their positions. To avoid the excessive current segment move, introduce move_one_curseg_info() function which does same work as move_curseg_info() only for a single current segment. Call move_one_curseg_info() in place of move_curseg_info() from update_curseg_info(). Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fsck/mount.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/fsck/mount.c b/fsck/mount.c
index 7ce885c..cd6b51b 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -2548,52 +2548,58 @@ int find_next_free_block(struct f2fs_sb_info *sbi, u64 *to, int left,
return -1;
}
-void move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left)
+static void move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left,
+ int i)
{
- int i, ret;
+ struct curseg_info *curseg = CURSEG_I(sbi, i);
+ struct f2fs_summary_block buf;
+ u32 old_segno;
+ u64 ssa_blk, to;
+ int ret;
- /* update summary blocks having nullified journal entries */
- for (i = 0; i < NO_CHECK_TYPE; i++) {
- struct curseg_info *curseg = CURSEG_I(sbi, i);
- struct f2fs_summary_block buf;
- u32 old_segno;
- u64 ssa_blk, to;
+ /* update original SSA too */
+ ssa_blk = GET_SUM_BLKADDR(sbi, curseg->segno);
+ ret = dev_write_block(curseg->sum_blk, ssa_blk);
+ ASSERT(ret >= 0);
- /* update original SSA too */
- ssa_blk = GET_SUM_BLKADDR(sbi, curseg->segno);
- ret = dev_write_block(curseg->sum_blk, ssa_blk);
- ASSERT(ret >= 0);
+ to = from;
+ ret = find_next_free_block(sbi, &to, left, i,
+ c.zoned_model == F2FS_ZONED_HM);
+ ASSERT(ret == 0);
- to = from;
- ret = find_next_free_block(sbi, &to, left, i,
- c.zoned_model == F2FS_ZONED_HM);
- ASSERT(ret == 0);
+ old_segno = curseg->segno;
+ curseg->segno = GET_SEGNO(sbi, to);
+ curseg->next_blkoff = OFFSET_IN_SEG(sbi, to);
+ curseg->alloc_type = c.zoned_model == F2FS_ZONED_HM ? LFS : SSR;
- old_segno = curseg->segno;
- curseg->segno = GET_SEGNO(sbi, to);
- curseg->next_blkoff = OFFSET_IN_SEG(sbi, to);
- curseg->alloc_type = c.zoned_model == F2FS_ZONED_HM ? LFS : SSR;
+ /* update new segno */
+ ssa_blk = GET_SUM_BLKADDR(sbi, curseg->segno);
+ ret = dev_read_block(&buf, ssa_blk);
+ ASSERT(ret >= 0);
- /* update new segno */
- ssa_blk = GET_SUM_BLKADDR(sbi, curseg->segno);
- ret = dev_read_block(&buf, ssa_blk);
- ASSERT(ret >= 0);
+ memcpy(curseg->sum_blk, &buf, SUM_ENTRIES_SIZE);
- memcpy(curseg->sum_blk, &buf, SUM_ENTRIES_SIZE);
+ /* update se->types */
+ reset_curseg(sbi, i);
- /* update se->types */
- reset_curseg(sbi, i);
+ FIX_MSG("Move curseg[%d] %x -> %x after %"PRIx64"\n",
+ i, old_segno, curseg->segno, from);
+}
- DBG(1, "Move curseg[%d] %x -> %x after %"PRIx64"\n",
- i, old_segno, curseg->segno, from);
- }
+void move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left)
+{
+ int i;
+
+ /* update summary blocks having nullified journal entries */
+ for (i = 0; i < NO_CHECK_TYPE; i++)
+ move_one_curseg_info(sbi, from, left, i);
}
void update_curseg_info(struct f2fs_sb_info *sbi, int type)
{
if (!relocate_curseg_offset(sbi, type))
return;
- move_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0);
+ move_one_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0, type);
}
void zero_journal_entries(struct f2fs_sb_info *sbi)