From patchwork Fri May 12 10:03:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Yu X-Patchwork-Id: 13239007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C1696C77B7F for ; Fri, 12 May 2023 10:04:29 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1pxPdS-0001bx-OJ; Fri, 12 May 2023 10:04:27 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pxPdQ-0001be-8S for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=9OGaAI6KWCZIi5QuBXlNlysRj9smTmNlfNfeT4/RIX4=; b=mxIlKpREfYvOZDDAGhStDBG7VL CByShBomEZfpP4WsBx0H7UeL13KBlkga04TQ6ifEnBGsy46jiZyDky9MnaPefAEdy5hp4/62KzvVa 3O9aq0wy30HCuEXYLGnbjauX9+NAEUukmrpY4RhExHEiEF3ORzaGime4yWGnetbCUS3s=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=9OGaAI6KWCZIi5QuBXlNlysRj9smTmNlfNfeT4/RIX4=; b=N lfOJg3Ehibtk3dXfhGa49MAX/Uiy93OE4NdnO9DS++izDDk3W/9BwOEC0ar7s9ro+0BzQIrZ5VPqF 1vYrCrFFa6AkZ0RS9mtg4AmAOFxIeGDjLcwo7Nv3flkVuD8ojLn3DZNeRVTlOx+PxmA67qS5ucmPK UaYeD9w+t/7ytk6s=; Received: from dfw.source.kernel.org ([139.178.84.217]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1pxPdQ-004LeM-Hs for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:25 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 277D36549A for ; Fri, 12 May 2023 10:04:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8CB10C433D2; Fri, 12 May 2023 10:04:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683885858; bh=vjqBAsfPouhQxFola4pEXzWAL5pk+TSfG0Ed+7gdtN4=; h=From:To:Cc:Subject:Date:From; b=n5uah4O+yZoznAXwp548veXBMfsY0p+YmJtHcMvkH9K7p6hRlfsSB+YtTbuhUX5Zm JvAHRHO9VxcPsqEV0KpI+hFjNx1p3d1tDpCFR6CFoQmxsB12y+s7VOmDavSDfyMOsC Yb/ktSjJSz0J5lCkO+6ih1jkdW5ligrN9eohUFOfoYnbfrmPL5vA4l8rPuZXsMchQU 0siBDUrrPlqRyIJQH3dS1Gt0nvoZNRZPilzV5+M2FwVvpRL7KnqCJB2974fQmbKlbv DhAHbPxSbyI4UDOohokEJ4A3H3G8ty3FHCldaNvuBWqgi6oMFxgJxNlGaVs3XLZ+Ni pBlICNAX0gYrA== From: Chao Yu To: jaegeuk@kernel.org Date: Fri, 12 May 2023 18:03:51 +0800 Message-Id: <20230512100354.4072489-1-chao@kernel.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Headers-End: 1pxPdQ-004LeM-Hs Subject: [f2fs-dev] [PATCH 1/4] fsck.f2fs: wrap openned codes into fsck_sanity_check_nid() X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-f2fs-devel@lists.sourceforge.net Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net read_all_xattrs() is the only user of fsck_sanity_check_nid(), wrap openned codes of read_all_xattrs() into fsck_sanity_check_nid(). Then fsck_sanity_check_nid() can be reused later. Signed-off-by: Chao Yu --- fsck/fsck.c | 16 ++++++++++++---- fsck/fsck.h | 3 +-- fsck/xattr.c | 12 +----------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 324c3d5..64db1e5 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -515,11 +515,19 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, } int fsck_sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, - struct f2fs_node *node_blk, - enum FILE_TYPE ftype, enum NODE_TYPE ntype, - struct node_info *ni) + enum FILE_TYPE ftype, enum NODE_TYPE ntype) { - return sanity_check_nid(sbi, nid, node_blk, ftype, ntype, ni); + struct f2fs_node *node_blk = NULL; + struct node_info ni; + int ret; + + node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1); + ASSERT(node_blk != NULL); + + ret = sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni); + + free(node_blk); + return ret; } static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, diff --git a/fsck/fsck.h b/fsck/fsck.h index dabd8b9..02dcff8 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -166,8 +166,7 @@ extern int fsck_chk_orphan_node(struct f2fs_sb_info *); extern int fsck_chk_quota_node(struct f2fs_sb_info *); extern int fsck_chk_quota_files(struct f2fs_sb_info *); extern int fsck_sanity_check_nid(struct f2fs_sb_info *, u32, - struct f2fs_node *, enum FILE_TYPE, enum NODE_TYPE, - struct node_info *); + enum FILE_TYPE, enum NODE_TYPE); extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32, enum FILE_TYPE, enum NODE_TYPE, u32 *, struct f2fs_compr_blk_cnt *, struct child_info *); diff --git a/fsck/xattr.c b/fsck/xattr.c index 8e66873..04c2879 100644 --- a/fsck/xattr.c +++ b/fsck/xattr.c @@ -25,17 +25,7 @@ void *read_all_xattrs(struct f2fs_sb_info *sbi, struct f2fs_node *inode) nid_t xnid = le32_to_cpu(inode->i.i_xattr_nid); if (c.func == FSCK && xnid) { - struct f2fs_node *node_blk = NULL; - struct node_info ni; - int ret; - - node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1); - ASSERT(node_blk != NULL); - - ret = fsck_sanity_check_nid(sbi, xnid, node_blk, - F2FS_FT_XATTR, TYPE_XATTR, &ni); - free(node_blk); - if (ret) + if (fsck_sanity_check_nid(sbi, xnid, F2FS_FT_XATTR, TYPE_XATTR)) return NULL; } From patchwork Fri May 12 10:03:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Yu X-Patchwork-Id: 13239006 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 26D56C77B7C for ; Fri, 12 May 2023 10:04:29 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1pxPdT-00009M-Nj; Fri, 12 May 2023 10:04:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pxPdS-00009G-BA for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:26 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Se97dhIGY3W+s+ekmGDeCmU+PPtEE1/bdv9KHq2fpFA=; b=caY4MSsmjdveiXo5AjE1+B/lgZ yv0kt7CYXFR7r/EEWiMMK4F83iNsB5vmS47mXswFXgRmvzgOd53R1ONVAIYvaIH1BkgTr9d0NXWcz deKS/PdH2oxL76Z/K1A3Gka5Ypoo/ogtUy5Msi7RjqNNj2fVqrN3CQInyGAVN0/a7XY8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Se97dhIGY3W+s+ekmGDeCmU+PPtEE1/bdv9KHq2fpFA=; b=NCJrSFxJYe3HzJqIb6tFQZ/xL8 9xk6uXGpV25DIw1aYOpQCyStrt7fFeGeSYa/2efRtr20ABM2AkwPX7pTPZUv3G8smsxIb129NLJGD XWiwQjGRTg0EstZizcCnKNWo8EkXeWnuDsG/fE9A/DXaGLpc3MNsyWYy68RyHYlCp5pc=; Received: from dfw.source.kernel.org ([139.178.84.217]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1pxPdS-004LeP-14 for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:26 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A44A060B7D for ; Fri, 12 May 2023 10:04:20 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14B68C4339B; Fri, 12 May 2023 10:04:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683885860; bh=0I9BcCMbg57042PZ9psBsrZc7/NzJdfA0pvmLIQsofc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sxVr3zAV2U9ua15LmyfsyrwR9kmds5ZYQqLmKCB2W5OTJmp50l0rbbpvz/i+c7S6r nxhh2mOSAOrzbN+J/oRF8QCXx2oDvMsSz/cknAuGowk88vvKITNSqRiZoLcFgvir4V ng+8viaujQX0LtejetXUPTLY1UZJ0IVDUaBq3PoDnCqIf4XPObc0E6oqJtmO2zYA3r VbTdWocw1OofgBCHMC9LVPvrmNzk8LPhIuWdMx0OBp+wYEwKslMhD2nBvUfLPq9OhF amVaTNbYDyFsZXERNU+R5S1WPzuDMAmdHGZT/Gjxq9phI7HE45Zl1i70yQ9U6SMLk/ KO1E6laIpOX3w== From: Chao Yu To: jaegeuk@kernel.org Date: Fri, 12 May 2023 18:03:52 +0800 Message-Id: <20230512100354.4072489-2-chao@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230512100354.4072489-1-chao@kernel.org> References: <20230512100354.4072489-1-chao@kernel.org> MIME-Version: 1.0 X-Headers-End: 1pxPdS-004LeP-14 Subject: [f2fs-dev] [PATCH 2/4] fsck.f2fs: use f2fs_is_valid_blkaddr() X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-f2fs-devel@lists.sourceforge.net Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net use f2fs_is_valid_blkaddr() instead of IS_VALID_BLK_ADDR() to check validity of data/node's block address. use is_valid_data_blkaddr() in sanity_check_nid() to check NULL_ADDR as NEW_ADDR, and print the value in error path explicitly. Signed-off-by: Chao Yu --- fsck/dump.c | 5 +++-- fsck/f2fs.h | 15 +-------------- fsck/fsck.c | 23 +++++++++++++---------- fsck/fsck.h | 2 ++ fsck/mount.c | 4 +++- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/fsck/dump.c b/fsck/dump.c index b8f6144..dd1f0ab 100644 --- a/fsck/dump.c +++ b/fsck/dump.c @@ -278,7 +278,8 @@ static void dump_data_blk(struct f2fs_sb_info *sbi, __u64 offset, u32 blkaddr) return; /* get data */ - if (blkaddr == NEW_ADDR || !IS_VALID_BLK_ADDR(sbi, blkaddr)) { + if (blkaddr == NEW_ADDR || + !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) { memset(buf, 0, F2FS_BLKSIZE); } else { int ret; @@ -588,7 +589,7 @@ int dump_node(struct f2fs_sb_info *sbi, nid_t nid, int force) DBG(1, "nat_entry.version [0x%x]\n", ni.version); DBG(1, "nat_entry.ino [0x%x]\n", ni.ino); - if (!IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) { + if (!f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) { MSG(force, "Invalid node blkaddr: %u\n\n", ni.blk_addr); goto out; } diff --git a/fsck/f2fs.h b/fsck/f2fs.h index e65644e..9791071 100644 --- a/fsck/f2fs.h +++ b/fsck/f2fs.h @@ -108,6 +108,7 @@ enum { META_SSA, META_MAX, META_POR, + DATA_GENERIC, }; #define MAX_RA_BLOCKS 64 @@ -520,20 +521,6 @@ static inline bool IS_VALID_NID(struct f2fs_sb_info *sbi, u32 nid) << (sbi->log_blocks_per_seg - 1))); } -static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr) -{ - if (addr == NULL_ADDR || addr == NEW_ADDR) - return 1; - - if (addr >= le64_to_cpu(F2FS_RAW_SUPER(sbi)->block_count) || - addr < SM_I(sbi)->main_blkaddr) { - DBG(1, "block addr [0x%x]\n", addr); - return 0; - } - /* next block offset will be checked at the end of fsck. */ - return 1; -} - static inline bool is_valid_data_blkaddr(block_t blkaddr) { if (blkaddr == NEW_ADDR || blkaddr == NULL_ADDR || diff --git a/fsck/fsck.c b/fsck/fsck.c index 64db1e5..9180deb 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -236,7 +236,7 @@ static int is_valid_summary(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, get_node_info(sbi, nid, &ni); - if (!IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) + if (!f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) goto out; /* read node_block */ @@ -405,12 +405,12 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, return -EINVAL; } - if (ni->blk_addr == NEW_ADDR) { - ASSERT_MSG("nid is NEW_ADDR. [0x%x]", nid); + if (!is_valid_data_blkaddr(ni->blk_addr)) { + ASSERT_MSG("nid->blk_addr is 0x%x. [0x%x]", ni->blk_addr, nid); return -EINVAL; } - if (!IS_VALID_BLK_ADDR(sbi, ni->blk_addr)) { + if (!f2fs_is_valid_blkaddr(sbi, ni->blk_addr, DATA_GENERIC)) { ASSERT_MSG("blkaddress is not valid. [0x%x]", ni->blk_addr); return -EINVAL; } @@ -676,7 +676,7 @@ void fsck_reada_node_block(struct f2fs_sb_info *sbi, u32 nid) if (nid != 0 && IS_VALID_NID(sbi, nid)) { get_node_info(sbi, nid, &ni); - if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) + if (f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC)) dev_reada_block(ni.blk_addr); } } @@ -1612,7 +1612,8 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, int casefolded, struct node_info ni; get_node_info(sbi, ino, &ni); - if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) { + if (f2fs_is_valid_blkaddr(sbi, ni.blk_addr, + DATA_GENERIC)) { dev_reada_block(ni.blk_addr); name_len = le16_to_cpu(dentry[i].name_len); if (name_len > 0) @@ -1867,7 +1868,7 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, int casefolded, return 0; } - if (!IS_VALID_BLK_ADDR(sbi, blk_addr)) { + if (!f2fs_is_valid_blkaddr(sbi, blk_addr, DATA_GENERIC)) { ASSERT_MSG("blkaddress is not valid. [0x%x]", blk_addr); return -EINVAL; } @@ -1939,7 +1940,8 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi) if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) { get_node_info(sbi, ino, &ni); if (!IS_VALID_NID(sbi, ino) || - !IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) { + !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, + DATA_GENERIC)) { free(orphan_blk); free(new_blk); return -EINVAL; @@ -1997,7 +1999,8 @@ int fsck_chk_quota_node(struct f2fs_sb_info *sbi) if (c.preen_mode == PREEN_MODE_1 && !c.fix_on) { get_node_info(sbi, ino, &ni); if (!IS_VALID_NID(sbi, ino) || - !IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) + !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, + DATA_GENERIC)) return -EINVAL; continue; } @@ -2136,7 +2139,7 @@ int fsck_chk_meta(struct f2fs_sb_info *sbi) */ continue; - if (!IS_VALID_BLK_ADDR(sbi, blk)) { + if (!f2fs_is_valid_blkaddr(sbi, blk, DATA_GENERIC)) { MSG(0, "\tError: nat entry[ino %u block_addr 0x%x]" " is in valid\n", ino, blk); diff --git a/fsck/fsck.h b/fsck/fsck.h index 02dcff8..89b1c6e 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -216,6 +216,8 @@ extern int f2fs_set_sit_bitmap(struct f2fs_sb_info *, u32); extern void fsck_init(struct f2fs_sb_info *); extern int fsck_verify(struct f2fs_sb_info *); extern void fsck_free(struct f2fs_sb_info *); +extern bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, + block_t blkaddr, int type); extern int f2fs_ra_meta_pages(struct f2fs_sb_info *, block_t, int, int); extern int f2fs_do_mount(struct f2fs_sb_info *); extern void f2fs_do_umount(struct f2fs_sb_info *); diff --git a/fsck/mount.c b/fsck/mount.c index 16c98cc..f0b0072 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -767,6 +767,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, return 0; break; case META_POR: + case DATA_GENERIC: if (blkaddr >= MAX_BLKADDR(sbi) || blkaddr < MAIN_BLKADDR(sbi)) return 0; @@ -1596,7 +1597,8 @@ static int f2fs_early_init_nid_bitmap(struct f2fs_sb_info *sbi) block_t addr; addr = le32_to_cpu(nat_in_journal(journal, i).block_addr); - if (!IS_VALID_BLK_ADDR(sbi, addr)) { + if (addr != NULL_ADDR && + !f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC)) { MSG(0, "\tError: f2fs_init_nid_bitmap: addr(%u) is invalid!!!\n", addr); journal->n_nats = cpu_to_le16(i); c.fix_on = 1; From patchwork Fri May 12 10:03:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Yu X-Patchwork-Id: 13239008 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B9376C7EE24 for ; Fri, 12 May 2023 10:04:30 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1pxPdV-0001Xb-RE; Fri, 12 May 2023 10:04:29 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pxPdV-0001XV-2A for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=zJvmdKDWcZPor4XEktqB1zvln09wBdpKlZzkIZkZ0Z0=; b=LJ7ktSv+88SZFlk/XuY8VnI2wF At7BwnW+FRHsNybPupoD10H5IM83Btr2x+Fvk3MHf5CTOL45Jkm4eUn3+WTS41g524AM0uVYnQXlQ LEE4jMv7FxC7hqi1KIgL6nQ520cUZWvtPX3w+GxMMW0MIfLnaLcSuQIYtiOg5QpsB8Ts=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=zJvmdKDWcZPor4XEktqB1zvln09wBdpKlZzkIZkZ0Z0=; b=l2ofkR9gSEDJh9WgNR3jj+WSFX 9IzZeWlsan2rodKnquDbSPQ9+kGFwyh6fqExQWr8tD9ISS0XuLFV5vaIPdMYSWZOFf3NeUlOJ2Xjm L+SVnM0AxqYojsHayQydMtiLJms2tDHib5SHpcYk3OHVTyYPz0jMOZ7HQQ0eErfJ5ntc=; Received: from dfw.source.kernel.org ([139.178.84.217]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1pxPdU-0003Ov-Aq for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:29 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 276D8654BB for ; Fri, 12 May 2023 10:04:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 90B0CC433EF; Fri, 12 May 2023 10:04:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683885861; bh=fRRt8IpBbE+fHPgkz53zREV8+DuYhsCsjIX+gtD+gw8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HYw4b0tzqDdoMtDlAJtJVjudJf5G60nojl9ismBXZRkWp8+X8kLgjVg6LSChBERuj BFje8ZTnjHZfn2DaVTBKgdOEQZK5lrLBEBojq0KgSWn/JrBaqWk9/kYwsEXluQE747 wrBYrW3OLun8rc7Rjw7+anST10xJeVAE+H4/8cG6QGSEknDeVTdXSX6VOhIFJS0c6I kBRruhkYKOrjjwlM6b0cB6eaQOgkQZFKJ0REKTJG+pb1wVoM1jomTmd5lDADa4S4ve +A1qpAT6fMqb7exyDf4s+W/3ot8isJWVjhqdz/EzjMNTj0qnBtKEOY+7PG1Hq12b1z LcqY+qLf064fA== From: Chao Yu To: jaegeuk@kernel.org Date: Fri, 12 May 2023 18:03:53 +0800 Message-Id: <20230512100354.4072489-3-chao@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230512100354.4072489-1-chao@kernel.org> References: <20230512100354.4072489-1-chao@kernel.org> MIME-Version: 1.0 X-Headers-End: 1pxPdU-0003Ov-Aq Subject: [f2fs-dev] [PATCH 3/4] fsck.f2fs: add more debug info in fsck_verify() X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-f2fs-devel@lists.sourceforge.net Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net In order to track details of stat info and repair flow. [FSCK] valid_block_count matching with CP [Fail] [0x2, 0x0] [FSCK] valid_node_count matching with CP (de lookup) [Fail] [0x1, 0x0] [FSCK] valid_node_count matching with CP (nat lookup) [Fail] [0x1, 0x0] [FSCK] valid_inode_count matched with CP [Fail] [0x1, 0x0] Info: flush_journal_entries() n_nats: 1, n_sits: 6 Info: write_checkpoint() cur_cp:1 Info: fix_checkpoint() cur_cp:1 Signed-off-by: Chao Yu --- fsck/fsck.c | 18 +++++++++++++----- fsck/mount.c | 7 ++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 9180deb..3650873 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -2407,6 +2407,8 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi) ret = f2fs_fsync_device(); ASSERT(ret >= 0); + + MSG(0, "Info: fix_checkpoint() cur_cp:%d\n", sbi->cur_cp); } static void fix_checkpoints(struct f2fs_sb_info *sbi) @@ -3284,7 +3286,8 @@ int fsck_verify(struct f2fs_sb_info *sbi) if (sbi->total_valid_block_count == fsck->chk.valid_blk_cnt) { printf(" [Ok..] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); } else { - printf(" [Fail] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); + printf(" [Fail] [0x%x, 0x%x]\n", sbi->total_valid_block_count, + (u32)fsck->chk.valid_blk_cnt); verify_failed = true; } @@ -3292,7 +3295,8 @@ int fsck_verify(struct f2fs_sb_info *sbi) if (sbi->total_valid_node_count == fsck->chk.valid_node_cnt) { printf(" [Ok..] [0x%x]\n", fsck->chk.valid_node_cnt); } else { - printf(" [Fail] [0x%x]\n", fsck->chk.valid_node_cnt); + printf(" [Fail] [0x%x, 0x%x]\n", sbi->total_valid_node_count, + fsck->chk.valid_node_cnt); verify_failed = true; } @@ -3300,7 +3304,8 @@ int fsck_verify(struct f2fs_sb_info *sbi) if (sbi->total_valid_node_count == fsck->chk.valid_nat_entry_cnt) { printf(" [Ok..] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); } else { - printf(" [Fail] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); + printf(" [Fail] [0x%x, 0x%x]\n", sbi->total_valid_node_count, + fsck->chk.valid_nat_entry_cnt); verify_failed = true; } @@ -3308,7 +3313,8 @@ int fsck_verify(struct f2fs_sb_info *sbi) if (sbi->total_valid_inode_count == fsck->chk.valid_inode_cnt) { printf(" [Ok..] [0x%x]\n", fsck->chk.valid_inode_cnt); } else { - printf(" [Fail] [0x%x]\n", fsck->chk.valid_inode_cnt); + printf(" [Fail] [0x%x, 0x%x]\n", sbi->total_valid_inode_count, + fsck->chk.valid_inode_cnt); verify_failed = true; } @@ -3317,7 +3323,9 @@ int fsck_verify(struct f2fs_sb_info *sbi) fsck->chk.sit_free_segs) { printf(" [Ok..] [0x%x]\n", fsck->chk.sit_free_segs); } else { - printf(" [Fail] [0x%x]\n", fsck->chk.sit_free_segs); + printf(" [Fail] [0x%x, 0x%x]\n", + le32_to_cpu(F2FS_CKPT(sbi)->free_segment_count), + fsck->chk.sit_free_segs); verify_failed = true; } diff --git a/fsck/mount.c b/fsck/mount.c index f0b0072..f19f081 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -2782,8 +2782,11 @@ void flush_journal_entries(struct f2fs_sb_info *sbi) int n_nats = flush_nat_journal_entries(sbi); int n_sits = flush_sit_journal_entries(sbi); - if (n_nats || n_sits) + if (n_nats || n_sits) { + MSG(0, "Info: flush_journal_entries() n_nats: %d, n_sits: %d\n", + n_nats, n_sits); write_checkpoints(sbi); + } } void flush_sit_entries(struct f2fs_sb_info *sbi) @@ -3259,6 +3262,8 @@ void write_checkpoint(struct f2fs_sb_info *sbi) ret = f2fs_fsync_device(); ASSERT(ret >= 0); + + MSG(0, "Info: write_checkpoint() cur_cp:%d\n", sbi->cur_cp); } void write_checkpoints(struct f2fs_sb_info *sbi) From patchwork Fri May 12 10:03:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chao Yu X-Patchwork-Id: 13239009 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 68A29C77B7C for ; Fri, 12 May 2023 10:04:34 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1pxPdX-0001cv-Db; Fri, 12 May 2023 10:04:32 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1pxPdV-0001cW-56 for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:30 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=WdRpcVU/uDzaHy+1nROgUt2/ZVf5zUCuFUOpgv1Liiw=; b=PxsYesPXv4S0qGmaa1eWAxudn/ LaAUadJAqQMj6CBVNZyw4239UFwndfju1w4Tbcc1KQ/REECoTAk1uT+nlrq5qNuRrzbNGEja2r9CA Ab/tfBRUyvL9zCg7tlNLDLrtW6XQ7eVKHcraySNuhnfEmO4NH5dkDa4Yy9qYs92Tj4s8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=WdRpcVU/uDzaHy+1nROgUt2/ZVf5zUCuFUOpgv1Liiw=; b=koEobWBqoZ3eBIhChm7y/5fvXC t5vZSM2aSemCUcISrogO+EcYtSUH/1pxqOofJ75h5MM8xi5IMKu0VxwuZqSQvEzNO+7UiU+UEYWkG LOXaQlOqslGoqoBpl0k49so8jfbaJc0XEgPGJCue2xqELmUfR1l/IbLI1p6I65nq6gA8=; Received: from dfw.source.kernel.org ([139.178.84.217]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1pxPdV-004Lee-2M for linux-f2fs-devel@lists.sourceforge.net; Fri, 12 May 2023 10:04:29 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AB0E4654C0 for ; Fri, 12 May 2023 10:04:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18B7FC4339B; Fri, 12 May 2023 10:04:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1683885863; bh=jV6GcFxI8VpmtBhdUqsK6u0LDXfmx2m/ww1aJrYz1IQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fenXtwVs0OOJ8kY/Lx7FJwKqc9E7qXQRd0aZP04MPC7tub3PgtJK89OQeZLyQVra8 05wXkqDioJaPgemjYTZACTEjRiPx9UuaR5pW5zUPY5jR0mxNqv8smEXYw+gqbiaq4u PUdFvG05XfdKyan1WkMSloDCbFNtmpC6TVPqhrhgE1hbLgViF/Ey5vAyxPZGdHIBVS Vxy+ziFHYUdUZct4NC/DapUU3FiOVYe6AkrgdeZ0md0QPutUm2bYVyjGtCwxUWIYxX qj1sK4Ls4XzQwZfnB5cvrIS4jPzUXWD2XRnxKWmwsBGpSuduRaQl96sqfjQjKFGS38 AgErPIZ61TmoQ== From: Chao Yu To: jaegeuk@kernel.org Date: Fri, 12 May 2023 18:03:54 +0800 Message-Id: <20230512100354.4072489-4-chao@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230512100354.4072489-1-chao@kernel.org> References: <20230512100354.4072489-1-chao@kernel.org> MIME-Version: 1.0 X-Headers-End: 1pxPdV-004Lee-2M Subject: [f2fs-dev] [PATCH 4/4] fsck.f2fs: lookup and relink root inode X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-f2fs-devel@lists.sourceforge.net Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net As Stephanos reported in mailing list: Info: checkpoint state = 1 : unmount [ASSERT] (sanity_check_nid: 362) --> nid[0x3] ino is 0 The root cause is root inode's nat entry is corrupted, this patch add logic to search root inode from all node blocks, try to relink root inode's nat to target node block. Before: Info: checkpoint state = 185 : trimmed nat_bits compacted_summary unmount [lookup_nat_in_journal:3085] ==> Found nid [0x3] in nat cache [ASSERT] (sanity_check_nat: 404) --> nid->blk_addr is 0x0. [0x3] Info: root inode is corrupted, search and relink it Info: possible root inode blkaddr: 0x5a00 [lookup_nat_in_journal:3085] ==> Found nid [0x3] in nat cache [ASSERT] (sanity_check_nat: 404) --> nid->blk_addr is 0x0. [0x3] [FSCK] Max image size: 94 MB, Free space: 12194 MB [FSCK] Unreachable nat entries [Ok..] [0x0] [FSCK] SIT valid block bitmap checking [Fail] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Fail] [0x2, 0x0] [FSCK] valid_node_count matching with CP (de lookup) [Fail] [0x1, 0x0] [FSCK] valid_node_count matching with CP (nat lookup) [Fail] [0x1, 0x0] [FSCK] valid_inode_count matched with CP [Fail] [0x1, 0x0] [FSCK] free segment_count matched with CP [Ok..] [0x17cd] [FSCK] next block offset is free [Ok..] [FSCK] fixing SIT types [FSCK] other corrupted bugs [Fail] Do you want to fix this partition? [Y/N] Y After: Info: checkpoint state = 185 : trimmed nat_bits compacted_summary unmount [lookup_nat_in_journal:3085] ==> Found nid [0x3] in nat cache [ASSERT] (sanity_check_nat: 404) --> nid->blk_addr is 0x0. [0x3] Info: root inode is corrupted, search and relink it Info: possible root inode blkaddr: 0x5a00 [FIX] (fsck_chk_root_inode: 730) --> Relink root inode, blkaddr: 0x5a00 update nat(nid:3) blkaddr [0x5a00] in journal [fsck_chk_dentry_blk:1978] [ 1] Dentry Block [0x6000] Done : dentries:0 in 214 slots (len:255) [fsck_chk_inode_blk:1244] Directory Inode: 0x3 [] depth: 1 has 0 files [FSCK] Max image size: 94 MB, Free space: 12194 MB [FSCK] Unreachable nat entries [Ok..] [0x0] [FSCK] SIT valid block bitmap checking [Ok..] [FSCK] Hard link checking for regular file [Ok..] [0x0] [FSCK] valid_block_count matching with CP [Ok..] [0x2] [FSCK] valid_node_count matching with CP (de lookup) [Ok..] [0x1] [FSCK] valid_node_count matching with CP (nat lookup) [Ok..] [0x1] [FSCK] valid_inode_count matched with CP [Ok..] [0x1] [FSCK] free segment_count matched with CP [Ok..] [0x17cd] [FSCK] next block offset is free [Ok..] [FSCK] fixing SIT types [FSCK] other corrupted bugs [Fail] Info: flush_journal_entries() n_nats: 1, n_sits: 6 Info: Duplicate valid checkpoint to mirror position 512 -> 1024 [write_nat_bits:1737] Writing NAT bits pages, at offset 0x000003ff Info: Write valid nat_bits in checkpoint Info: write_checkpoint() cur_cp:1 [write_nat_bits:1737] Writing NAT bits pages, at offset 0x000003ff Info: Write valid nat_bits in checkpoint Info: fix_checkpoint() cur_cp:1 Signed-off-by: Chao Yu --- fsck/fsck.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++--- fsck/fsck.h | 4 ++ fsck/main.c | 4 ++ fsck/mount.c | 18 +++++++ 4 files changed, 167 insertions(+), 7 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index 3650873..d03f1da 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -386,14 +386,9 @@ err: return -1; } -static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, - struct f2fs_node *node_blk, - enum FILE_TYPE ftype, enum NODE_TYPE ntype, - struct node_info *ni) +static int sanity_check_nat(struct f2fs_sb_info *sbi, u32 nid, + struct node_info *ni) { - struct f2fs_fsck *fsck = F2FS_FSCK(sbi); - int ret; - if (!IS_VALID_NID(sbi, nid)) { ASSERT_MSG("nid is not valid. [0x%x]", nid); return -EINVAL; @@ -415,6 +410,28 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, return -EINVAL; } + return 0; +} + +int fsck_sanity_check_nat(struct f2fs_sb_info *sbi, u32 nid) +{ + struct node_info ni; + + return sanity_check_nat(sbi, nid, &ni); +} + +static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, + struct f2fs_node *node_blk, + enum FILE_TYPE ftype, enum NODE_TYPE ntype, + struct node_info *ni) +{ + struct f2fs_fsck *fsck = F2FS_FSCK(sbi); + int ret; + + ret = sanity_check_nat(sbi, nid, ni); + if (ret) + return ret; + ret = dev_read_block(node_blk, ni->blk_addr); ASSERT(ret >= 0); @@ -609,6 +626,123 @@ err: return -EINVAL; } +static bool is_sit_bitmap_set(struct f2fs_sb_info *sbi, u32 blk_addr) +{ + struct seg_entry *se; + u32 offset; + + se = get_seg_entry(sbi, GET_SEGNO(sbi, blk_addr)); + offset = OFFSET_IN_SEG(sbi, blk_addr); + + return f2fs_test_bit(offset, + (const char *)se->cur_valid_map) != 0; +} + +int fsck_chk_root_inode(struct f2fs_sb_info *sbi) +{ + struct f2fs_node *node_blk; + int segment_count = SM_I(sbi)->main_segments; + int segno; + bool valid_bitmap = true; + block_t last_blkaddr = NULL_ADDR; + nid_t root_ino = sbi->root_ino_num; + u64 last_ctime = 0; + u32 last_ctime_nsec = 0; + int ret = -EINVAL; + + node_blk = calloc(BLOCK_SZ, 1); + ASSERT(node_blk); + + MSG(0, "Info: root inode is corrupted, search and relink it\n"); + +retry: + for (segno = 0; segno < segment_count; segno++) { + struct seg_entry *se = get_seg_entry(sbi, segno); + block_t blkaddr = START_BLOCK(sbi, segno); + int ret; + int i; + + if (IS_DATASEG(se->type)) + continue; + + dev_readahead(blkaddr << F2FS_BLKSIZE_BITS, + sbi->blocks_per_seg << F2FS_BLKSIZE_BITS); + + for (i = 0; i < sbi->blocks_per_seg; i++, blkaddr++) { + if (valid_bitmap ^ is_sit_bitmap_set(sbi, blkaddr)) + continue; + + ret = dev_read_block(node_blk, blkaddr); + ASSERT(ret >= 0); + + if (le32_to_cpu(node_blk->footer.ino) != + root_ino || + le32_to_cpu(node_blk->footer.nid) != + root_ino) + continue; + + if (!IS_INODE(node_blk)) + continue; + + if (le32_to_cpu(node_blk->i.i_generation) || + le32_to_cpu(node_blk->i.i_namelen)) + continue; + break; + } + + if (i == sbi->blocks_per_seg) + continue; + + if (valid_bitmap) { + last_blkaddr = blkaddr; + MSG(0, "Info: possible root inode blkaddr: 0x%x\n", + last_blkaddr); + goto fix; + } + + if (last_blkaddr == NULL_ADDR) + goto init; + if (le64_to_cpu(node_blk->i.i_ctime) < last_ctime) + continue; + if (le64_to_cpu(node_blk->i.i_ctime) == last_ctime && + le32_to_cpu(node_blk->i.i_ctime_nsec) <= + last_ctime_nsec) + continue; +init: + last_blkaddr = blkaddr; + last_ctime = le64_to_cpu(node_blk->i.i_ctime); + last_ctime_nsec = le32_to_cpu(node_blk->i.i_ctime_nsec); + + MSG(0, "Info: possible root inode blkaddr: %u\n", + last_blkaddr); + } + + if (valid_bitmap) { + valid_bitmap = false; + goto retry; + } +fix: + if (!last_blkaddr) { + MSG(0, "Info: there is no valid root inode\n"); + } else if (c.fix_on) { + struct f2fs_fsck *fsck = F2FS_FSCK(sbi); + + FIX_MSG("Relink root inode, blkaddr: 0x%x", last_blkaddr); + update_nat_journal_blkaddr(sbi, root_ino, last_blkaddr); + update_nat_blkaddr(sbi, root_ino, root_ino, last_blkaddr); + + if (f2fs_test_bit(root_ino, fsck->nat_area_bitmap)) + f2fs_clear_bit(root_ino, fsck->nat_area_bitmap); + fsck->chk.valid_nat_entry_cnt++; + + if (!f2fs_test_sit_bitmap(sbi, last_blkaddr)) + f2fs_set_sit_bitmap(sbi, last_blkaddr); + ret = 0; + } + free(node_blk); + return ret; +} + static inline void get_extent_info(struct extent_info *ext, struct f2fs_extent *i_ext) { diff --git a/fsck/fsck.h b/fsck/fsck.h index 89b1c6e..0f7caf4 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -167,9 +167,11 @@ extern int fsck_chk_quota_node(struct f2fs_sb_info *); extern int fsck_chk_quota_files(struct f2fs_sb_info *); extern int fsck_sanity_check_nid(struct f2fs_sb_info *, u32, enum FILE_TYPE, enum NODE_TYPE); +extern int fsck_sanity_check_nat(struct f2fs_sb_info *sbi, u32 nid); extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32, enum FILE_TYPE, enum NODE_TYPE, u32 *, struct f2fs_compr_blk_cnt *, struct child_info *); +extern int fsck_chk_root_inode(struct f2fs_sb_info *); extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE, struct f2fs_node *, u32 *, struct f2fs_compr_blk_cnt *, struct node_info *, struct child_info *); @@ -208,6 +210,8 @@ extern void update_sum_entry(struct f2fs_sb_info *, block_t, struct f2fs_summary *); extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *); extern void nullify_nat_entry(struct f2fs_sb_info *, u32); +extern void update_nat_journal_blkaddr(struct f2fs_sb_info *sbi, u32 nid, + block_t blkaddr); extern void rewrite_sit_area_bitmap(struct f2fs_sb_info *); extern void build_nat_area_bitmap(struct f2fs_sb_info *); extern void build_sit_area_bitmap(struct f2fs_sb_info *); diff --git a/fsck/main.c b/fsck/main.c index b01b52c..e8c3dc4 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -885,6 +885,10 @@ static int do_fsck(struct f2fs_sb_info *sbi) } } fsck_chk_orphan_node(sbi); + + if (fsck_sanity_check_nat(sbi, sbi->root_ino_num)) + fsck_chk_root_inode(sbi); + fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num, F2FS_FT_DIR, TYPE_INODE, &blk_cnt, &cbc, NULL); fsck_chk_quota_files(sbi); diff --git a/fsck/mount.c b/fsck/mount.c index f19f081..4c74888 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -3132,6 +3132,24 @@ void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid) free(nat_block); } +void update_nat_journal_blkaddr(struct f2fs_sb_info *sbi, u32 nid, + block_t blkaddr) +{ + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); + struct f2fs_journal *journal = &curseg->sum_blk->journal; + int i; + + for (i = 0; i < nats_in_cursum(journal); i++) { + if (le32_to_cpu(nid_in_journal(journal, i)) == nid) { + nat_in_journal(journal, i).block_addr = + cpu_to_le32(blkaddr); + MSG(0, "update nat(nid:%d) blkaddr [0x%x] in journal\n", + nid, blkaddr); + return; + } + } +} + void duplicate_checkpoint(struct f2fs_sb_info *sbi) { struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);