Refactor looped node chain detected logic for cleanup as kernel does. Suggested-by: Chao Yu <c...@kernel.org> Signed-off-by: Chunhai Guo <guochun...@vivo.com> --- fsck/mount.c | 115 ++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 60 deletions(-)
diff --git a/fsck/mount.c b/fsck/mount.c index e5ffb2602b9e..b4eb9ffeb685 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -3492,32 +3492,6 @@ static void destroy_fsync_dnodes(struct list_head *head) del_fsync_inode(entry); } -static int find_node_blk_fast(struct f2fs_sb_info *sbi, block_t *blkaddr_fast, - struct f2fs_node *node_blk_fast, bool *is_detecting) -{ - int i, err; - - for (i = 0; i < 2; i++) { - if (!f2fs_is_valid_blkaddr(sbi, *blkaddr_fast, META_POR)) { - *is_detecting = false; - return 0; - } - - err = dev_read_block(node_blk_fast, *blkaddr_fast); - if (err) - return err; - - if (!is_recoverable_dnode(sbi, node_blk_fast)) { - *is_detecting = false; - return 0; - } - - *blkaddr_fast = next_blkaddr_of_node(node_blk_fast); - } - - return 0; -} - static int loop_node_chain_fix(block_t blkaddr_fast, struct f2fs_node *node_blk_fast, block_t blkaddr, struct f2fs_node *node_blk) @@ -3560,6 +3534,58 @@ static int loop_node_chain_fix(block_t blkaddr_fast, return err; } +/* Detect looped node chain with Floyd's cycle detection algorithm. */ +static int sanity_check_node_chain(struct f2fs_sb_info *sbi, + block_t *blkaddr_fast, struct f2fs_node *node_blk_fast, + block_t blkaddr, struct f2fs_node *node_blk, + bool *is_detecting) +{ + int i, err; + + if (!*is_detecting) + return 0; + + for (i = 0; i < 2; i++) { + if (!f2fs_is_valid_blkaddr(sbi, *blkaddr_fast, META_POR)) { + *is_detecting = false; + return 0; + } + + err = dev_read_block(node_blk_fast, *blkaddr_fast); + if (err) + return err; + + if (!is_recoverable_dnode(sbi, node_blk_fast)) { + *is_detecting = false; + return 0; + } + + *blkaddr_fast = next_blkaddr_of_node(node_blk_fast); + } + + if (*blkaddr_fast != blkaddr) + return 0; + + ASSERT_MSG("\tdetect looped node chain, blkaddr:%u\n", blkaddr); + if (!c.fix_on) + return -1; + + err = loop_node_chain_fix(NEXT_FREE_BLKADDR(sbi, + CURSEG_I(sbi, CURSEG_WARM_NODE)), + node_blk_fast, blkaddr, node_blk); + if (err) + return err; + + /* Since we call get_fsync_inode() to ensure there are no + * duplicate inodes in the inode_list even if there are + * duplicate blkaddr, we can continue running after fixing the + * looped node chain. + */ + *is_detecting = false; + + return 0; +} + static int find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head) { struct curseg_info *curseg; @@ -3608,42 +3634,11 @@ static int find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head) next: blkaddr = next_blkaddr_of_node(node_blk); - /* Below we will detect looped node chain with Floyd's cycle - * detection algorithm. - */ - if (!is_detecting) - continue; - - err = find_node_blk_fast(sbi, &blkaddr_fast, - node_blk_fast, &is_detecting); + err = sanity_check_node_chain(sbi, &blkaddr_fast, + node_blk_fast, blkaddr, node_blk, + &is_detecting); if (err) break; - - if (!is_detecting) - continue; - - if (blkaddr_fast != blkaddr) - continue; - - ASSERT_MSG("\tdetect looped node chain, blkaddr:%u\n", - blkaddr); - - if (!c.fix_on) { - err = -1; - break; - } - - err = loop_node_chain_fix(NEXT_FREE_BLKADDR(sbi, curseg), - node_blk_fast, blkaddr, node_blk); - if (err) - break; - - /* Since we call get_fsync_inode() to ensure there are no - * duplicate inodes in the inode_list even if there are - * duplicate blkaddr, we can continue running after fixing the - * looped node chain. - */ - is_detecting = false; } free(node_blk_fast); -- 2.25.1 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel