From patchwork Thu May 5 16:05:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12839722 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1CCC5C433FE for ; Thu, 5 May 2022 16:05:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381659AbiEEQJd (ORCPT ); Thu, 5 May 2022 12:09:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57886 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381637AbiEEQJd (ORCPT ); Thu, 5 May 2022 12:09:33 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0B835C366 for ; Thu, 5 May 2022 09:05:52 -0700 (PDT) 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 7CBFB61D76 for ; Thu, 5 May 2022 16:05:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DBED6C385AE; Thu, 5 May 2022 16:05:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1651766751; bh=p3puRW/CAnYP4DzSfwL1mEQ/UWEN+lz6RDrOX204SBE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=jW0gsrciHVgIZ3ImuGi85cTzmnb0FglszLr87FziysmDbKdkASXF4iFIOeTG+6rqK CTS/YNCJLrzhBtckYh1n/1IcgiBgErtQDq88jlZoJNmTWHiCgsEBpNjEG+ZwUOWSpW lAh6W1DXOe7b/YWQZ6Vk8Gj3GixcGp8flDTfVUPipGx/vfX0cJsXu7HYovUdqe9vx6 UOgMIRozI1T4EQIUzlpMX9y3/+ZS8duDkIV7a5ALFQ/rDFINSfiLlquWdAZsD0EaY5 7HvkpYbWdFAoHAiLxKEn/L7kiP9Dl/oPpsKVIuJS1m1aoJrTaQ+zNuWveoSnAet789 ugKHjlX5cYthA== Subject: [PATCH 1/3] xfs_repair: detect v5 featureset mismatches in secondary supers From: "Darrick J. Wong" To: sandeen@sandeen.net, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Thu, 05 May 2022 09:05:51 -0700 Message-ID: <165176675148.248791.14783205262181556770.stgit@magnolia> In-Reply-To: <165176674590.248791.17672675617466150793.stgit@magnolia> References: <165176674590.248791.17672675617466150793.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Make sure we detect and correct mismatches between the V5 features described in the primary and the secondary superblocks. Signed-off-by: Darrick J. Wong --- repair/agheader.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/repair/agheader.c b/repair/agheader.c index d8f912f2..650ffb2e 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -220,6 +220,92 @@ compare_sb(xfs_mount_t *mp, xfs_sb_t *sb) return(XR_OK); } +/* + * If the fs feature bits on a secondary superblock don't match the + * primary, we need to update them. + */ +static inline int +check_v5_feature_mismatch( + struct xfs_mount *mp, + xfs_agnumber_t agno, + struct xfs_sb *sb) +{ + bool dirty = false; + + if (!xfs_has_crc(mp) || agno == 0) + return 0; + + if (mp->m_sb.sb_features_compat != sb->sb_features_compat) { + if (no_modify) { + do_warn( + _("would fix compat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_compat, + sb->sb_features_compat); + } else { + do_warn( + _("will fix compat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_compat, + sb->sb_features_compat); + dirty = true; + } + } + + if ((mp->m_sb.sb_features_incompat ^ sb->sb_features_incompat) & + ~XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR) { + if (no_modify) { + do_warn( + _("would fix incompat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_incompat, + sb->sb_features_incompat); + } else { + do_warn( + _("will fix incompat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_incompat, + sb->sb_features_incompat); + dirty = true; + } + } + + if (mp->m_sb.sb_features_ro_compat != sb->sb_features_ro_compat) { + if (no_modify) { + do_warn( + _("would fix ro compat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_ro_compat, + sb->sb_features_ro_compat); + } else { + do_warn( + _("will fix ro compat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_ro_compat, + sb->sb_features_ro_compat); + dirty = true; + } + } + + if (mp->m_sb.sb_features_log_incompat != sb->sb_features_log_incompat) { + if (no_modify) { + do_warn( + _("would fix log incompat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_log_incompat, + sb->sb_features_log_incompat); + } else { + do_warn( + _("will fix log incompat feature mismatch in AG %u super, 0x%x != 0x%x\n"), + agno, mp->m_sb.sb_features_log_incompat, + sb->sb_features_log_incompat); + dirty = true; + } + } + + if (!dirty) + return 0; + + sb->sb_features_compat = mp->m_sb.sb_features_compat; + sb->sb_features_ro_compat = mp->m_sb.sb_features_ro_compat; + sb->sb_features_incompat = mp->m_sb.sb_features_incompat; + sb->sb_features_log_incompat = mp->m_sb.sb_features_log_incompat; + return XR_AG_SB_SEC; +} + /* * Possible fields that may have been set at mkfs time, * sb_inoalignmt, sb_unit, sb_width and sb_dirblklog. @@ -452,6 +538,8 @@ secondary_sb_whack( rval |= XR_AG_SB_SEC; } + rval |= check_v5_feature_mismatch(mp, i, sb); + if (xfs_sb_version_needsrepair(sb)) { if (i == 0) { if (!no_modify) From patchwork Thu May 5 16:05:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12839726 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA8F2C433EF for ; Thu, 5 May 2022 16:06:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1381650AbiEEQJo (ORCPT ); Thu, 5 May 2022 12:09:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58050 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381646AbiEEQJl (ORCPT ); Thu, 5 May 2022 12:09:41 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A80295C373 for ; Thu, 5 May 2022 09:06:00 -0700 (PDT) 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 ams.source.kernel.org (Postfix) with ESMTPS id C52D8B82DF4 for ; Thu, 5 May 2022 16:05:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76B54C385A8; Thu, 5 May 2022 16:05:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1651766757; bh=86XKwfLlWsGTt1xv6NoLEKVHZAvpZ3bgbme9YsBYFOA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=SD7301dE9yaLC/5p42LtC6+jU4J+yRTvLqBkNJC86vzZC8i36BQKjvJe7Lao/ddly ijbSj9utPMHXgzJO9QD79Tm2cdGNHGLEPyQwI9tKp9wW6KV9aoPijmGANFVVaA+jHG mxOtfW3Inkl27bJcgOSAu/GpLzKwtFelDeniCbIGyTpNR4HREjL2ISZl9s9haNUkm0 MMxN8Cu4Uh8YJW5fNbFCaOTySP7CDdiP4j5gTKufnodrHqDOutMJzInwF9luGrRNwK 4L7i1/hYrhg3aI8gUKsyQV1Mm9hI6uEOzGsymjuAsBCAKOWybibBZPpKTNEO9Bcg/a pKbAVJkTEkMoA== Subject: [PATCH 2/3] xfs_repair: improve checking of existing rmap and refcount btrees From: "Darrick J. Wong" To: sandeen@sandeen.net, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Thu, 05 May 2022 09:05:57 -0700 Message-ID: <165176675706.248791.4099817268523543427.stgit@magnolia> In-Reply-To: <165176674590.248791.17672675617466150793.stgit@magnolia> References: <165176674590.248791.17672675617466150793.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong There are a few deficiencies in the xfs_repair functions that check the existing reverse mapping and reference count btrees. First of all, we don't report corruption or IO errors if we can't read the ondisk metadata. Second, we don't consistently warn if we cannot allocate memory to perform the check. Add the missing warnings, and simplify the calling convention since we don't need the extra layer of do_error logging in phase4.c. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 20 ++++------------- repair/rmap.c | 65 ++++++++++++++++++++++++++++++++++++++----------------- repair/rmap.h | 4 ++- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/repair/phase4.c b/repair/phase4.c index 2260f6a3..746e0ccd 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -173,11 +173,7 @@ _("unable to add AG %u metadata reverse-mapping data.\n"), agno); do_error( _("unable to merge AG %u metadata reverse-mapping data.\n"), agno); - error = rmaps_verify_btree(wq->wq_ctx, agno); - if (error) - do_error( -_("%s while checking reverse-mappings"), - strerror(-error)); + rmaps_verify_btree(wq->wq_ctx, agno); } static void @@ -212,17 +208,11 @@ _("%s while fixing inode reflink flags.\n"), static void check_refcount_btrees( - struct workqueue*wq, - xfs_agnumber_t agno, - void *arg) + struct workqueue *wq, + xfs_agnumber_t agno, + void *arg) { - int error; - - error = check_refcounts(wq->wq_ctx, agno); - if (error) - do_error( -_("%s while checking reference counts"), - strerror(-error)); + check_refcounts(wq->wq_ctx, agno); } static void diff --git a/repair/rmap.c b/repair/rmap.c index e48f6c1e..b76a149d 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -974,7 +974,7 @@ rmap_is_good( /* * Compare the observed reverse mappings against what's in the ag btree. */ -int +void rmaps_verify_btree( struct xfs_mount *mp, xfs_agnumber_t agno) @@ -989,21 +989,26 @@ rmaps_verify_btree( int error; if (!xfs_has_rmapbt(mp)) - return 0; + return; if (rmapbt_suspect) { if (no_modify && agno == 0) do_warn(_("would rebuild corrupt rmap btrees.\n")); - return 0; + return; } /* Create cursors to refcount structures */ error = rmap_init_cursor(agno, &rm_cur); - if (error) - return error; + if (error) { + do_warn(_("Not enough memory to check reverse mappings.\n")); + return; + } error = -libxfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); - if (error) + if (error) { + do_warn(_("Could not read AGF %u to check rmap btree.\n"), + agno); goto err; + } /* Leave the per-ag data "uninitialized" since we rewrite it later */ pag = libxfs_perag_get(mp, agno); @@ -1011,15 +1016,20 @@ rmaps_verify_btree( bt_cur = libxfs_rmapbt_init_cursor(mp, NULL, agbp, pag); if (!bt_cur) { - error = -ENOMEM; + do_warn(_("Not enough memory to check reverse mappings.\n")); goto err; } rm_rec = pop_slab_cursor(rm_cur); while (rm_rec) { error = rmap_lookup(bt_cur, rm_rec, &tmp, &have); - if (error) + if (error) { + do_warn( +_("Could not read reverse-mapping record for (%u/%u).\n"), + agno, rm_rec->rm_startblock); goto err; + } + /* * Using the range query is expensive, so only do it if * the regular lookup doesn't find anything or if it doesn't @@ -1029,8 +1039,12 @@ rmaps_verify_btree( (!have || !rmap_is_good(rm_rec, &tmp))) { error = rmap_lookup_overlapped(bt_cur, rm_rec, &tmp, &have); - if (error) + if (error) { + do_warn( +_("Could not read reverse-mapping record for (%u/%u).\n"), + agno, rm_rec->rm_startblock); goto err; + } } if (!have) { do_warn( @@ -1088,7 +1102,6 @@ _("Incorrect reverse-mapping: saw (%u/%u) %slen %u owner %"PRId64" %s%soff \ if (agbp) libxfs_buf_relse(agbp); free_slab_cursor(&rm_cur); - return 0; } /* @@ -1335,7 +1348,7 @@ refcount_avoid_check(void) /* * Compare the observed reference counts against what's in the ag btree. */ -int +void check_refcounts( struct xfs_mount *mp, xfs_agnumber_t agno) @@ -1351,21 +1364,26 @@ check_refcounts( int error; if (!xfs_has_reflink(mp)) - return 0; + return; if (refcbt_suspect) { if (no_modify && agno == 0) do_warn(_("would rebuild corrupt refcount btrees.\n")); - return 0; + return; } /* Create cursors to refcount structures */ error = init_refcount_cursor(agno, &rl_cur); - if (error) - return error; + if (error) { + do_warn(_("Not enough memory to check refcount data.\n")); + return; + } error = -libxfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); - if (error) + if (error) { + do_warn(_("Could not read AGF %u to check refcount btree.\n"), + agno); goto err; + } /* Leave the per-ag data "uninitialized" since we rewrite it later */ pag = libxfs_perag_get(mp, agno); @@ -1373,7 +1391,7 @@ check_refcounts( bt_cur = libxfs_refcountbt_init_cursor(mp, NULL, agbp, pag); if (!bt_cur) { - error = -ENOMEM; + do_warn(_("Not enough memory to check refcount data.\n")); goto err; } @@ -1382,8 +1400,12 @@ check_refcounts( /* Look for a refcount record in the btree */ error = -libxfs_refcount_lookup_le(bt_cur, rl_rec->rc_startblock, &have); - if (error) + if (error) { + do_warn( +_("Could not read reference count record for (%u/%u).\n"), + agno, rl_rec->rc_startblock); goto err; + } if (!have) { do_warn( _("Missing reference count record for (%u/%u) len %u count %u\n"), @@ -1393,8 +1415,12 @@ _("Missing reference count record for (%u/%u) len %u count %u\n"), } error = -libxfs_refcount_get_rec(bt_cur, &tmp, &i); - if (error) + if (error) { + do_warn( +_("Could not read reference count record for (%u/%u).\n"), + agno, rl_rec->rc_startblock); goto err; + } if (!i) { do_warn( _("Missing reference count record for (%u/%u) len %u count %u\n"), @@ -1425,7 +1451,6 @@ _("Incorrect reference count: saw (%u/%u) len %u nlinks %u; should be (%u/%u) le if (agbp) libxfs_buf_relse(agbp); free_slab_cursor(&rl_cur); - return 0; } /* diff --git a/repair/rmap.h b/repair/rmap.h index e5a6a3b4..8d176cb3 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -28,7 +28,7 @@ extern int rmap_store_ag_btree_rec(struct xfs_mount *, xfs_agnumber_t); extern size_t rmap_record_count(struct xfs_mount *, xfs_agnumber_t); extern int rmap_init_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void rmap_avoid_check(void); -extern int rmaps_verify_btree(struct xfs_mount *, xfs_agnumber_t); +void rmaps_verify_btree(struct xfs_mount *mp, xfs_agnumber_t agno); extern int64_t rmap_diffkeys(struct xfs_rmap_irec *kp1, struct xfs_rmap_irec *kp2); @@ -39,7 +39,7 @@ extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); extern size_t refcount_record_count(struct xfs_mount *, xfs_agnumber_t); extern int init_refcount_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void refcount_avoid_check(void); -extern int check_refcounts(struct xfs_mount *, xfs_agnumber_t); +void check_refcounts(struct xfs_mount *mp, xfs_agnumber_t agno); extern void record_inode_reflink_flag(struct xfs_mount *, struct xfs_dinode *, xfs_agnumber_t, xfs_agino_t, xfs_ino_t); From patchwork Thu May 5 16:06:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12839727 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CB6AC433EF for ; Thu, 5 May 2022 16:06:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1353302AbiEEQJr (ORCPT ); Thu, 5 May 2022 12:09:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1381647AbiEEQJq (ORCPT ); Thu, 5 May 2022 12:09:46 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 011F35C641 for ; Thu, 5 May 2022 09:06:06 -0700 (PDT) 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 ams.source.kernel.org (Postfix) with ESMTPS id 682CBB82C77 for ; Thu, 5 May 2022 16:06:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 16C5FC385A4; Thu, 5 May 2022 16:06:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1651766763; bh=Cd6mxD+dGh/k+eAcAqlMYDFwXWanxxwEMfuqx8FvjmU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=kAVUE6iTqfdnD0rztRYHG/hQanhyY0HP8Vvu7sNZ2IcRbYlD9LBVU0Ks59wtJCwal q2Cr/iwy2U5+pYbR8wAjj5eBnsz2OICx3GqF8SYmZHBkOEl5CI/eBwM0cQfR4hDDHJ ZCNX7rh53hylHN3uDxYD8MJzg+yTkABAhCI8AU2DEvzb9Le/+RfqsQLChfst1aCgsu 6dKrT98gLWhOBuUSU7TJf4GoLVJkLuq30BYeCXWV1umy2gObKWqoyJJmDLk5LFViiz 7Df+R7AQS2mN2gXFKLPW7+4g8ZrxDTzJDwBzUvEvgFA2bERGCzOji/iXUp6NyU2ldQ WXCuwVIUi+/1w== Subject: [PATCH 3/3] xfs_repair: check the ftype of dot and dotdot directory entries From: "Darrick J. Wong" To: sandeen@sandeen.net, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Thu, 05 May 2022 09:06:02 -0700 Message-ID: <165176676265.248791.9813054389307375890.stgit@magnolia> In-Reply-To: <165176674590.248791.17672675617466150793.stgit@magnolia> References: <165176674590.248791.17672675617466150793.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong The long-format directory block checking code skips the filetype check for the '.' and '..' entries, even though they're part of the ondisk format. This leads to repair failing to catch subtle corruption at the start of a directory. Found by fuzzing bu[0].filetype = zeroes in xfs/386. Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen --- repair/phase6.c | 79 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index 8fcd4d36..c04b2e09 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1400,6 +1400,48 @@ dir2_kill_block( _("directory shrink failed (%d)\n"), error); } +static inline void +check_longform_ftype( + struct xfs_mount *mp, + struct xfs_inode *ip, + xfs_dir2_data_entry_t *dep, + ino_tree_node_t *irec, + int ino_offset, + struct dir_hash_tab *hashtab, + xfs_dir2_dataptr_t addr, + struct xfs_da_args *da, + struct xfs_buf *bp) +{ + xfs_ino_t inum = be64_to_cpu(dep->inumber); + uint8_t dir_ftype; + uint8_t ino_ftype; + + if (!xfs_has_ftype(mp)) + return; + + dir_ftype = libxfs_dir2_data_get_ftype(mp, dep); + ino_ftype = get_inode_ftype(irec, ino_offset); + + if (dir_ftype == ino_ftype) + return; + + if (no_modify) { + do_warn( +_("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ip->i_ino, inum); + return; + } + + do_warn( +_("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), + dir_ftype, ino_ftype, + ip->i_ino, inum); + libxfs_dir2_data_put_ftype(mp, dep, ino_ftype); + libxfs_dir2_data_log_entry(da, bp, dep); + dir_hash_update_ftype(hashtab, addr, ino_ftype); +} + /* * process a data block, also checks for .. entry * and corrects it to match what we think .. should be @@ -1737,6 +1779,11 @@ longform_dir2_entry_check_data( libxfs_dir2_data_log_entry(&da, bp, dep); } } + + if (!nbad) + check_longform_ftype(mp, ip, dep, irec, + ino_offset, hashtab, addr, &da, + bp); continue; } ASSERT(no_modify || libxfs_verify_dir_ino(mp, inum)); @@ -1765,6 +1812,11 @@ longform_dir2_entry_check_data( libxfs_dir2_data_log_entry(&da, bp, dep); } } + + if (!nbad) + check_longform_ftype(mp, ip, dep, irec, + ino_offset, hashtab, addr, &da, + bp); *need_dot = 0; continue; } @@ -1775,31 +1827,8 @@ longform_dir2_entry_check_data( continue; /* validate ftype field if supported */ - if (xfs_has_ftype(mp)) { - uint8_t dir_ftype; - uint8_t ino_ftype; - - dir_ftype = libxfs_dir2_data_get_ftype(mp, dep); - ino_ftype = get_inode_ftype(irec, ino_offset); - - if (dir_ftype != ino_ftype) { - if (no_modify) { - do_warn( - _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), - dir_ftype, ino_ftype, - ip->i_ino, inum); - } else { - do_warn( - _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"), - dir_ftype, ino_ftype, - ip->i_ino, inum); - libxfs_dir2_data_put_ftype(mp, dep, ino_ftype); - libxfs_dir2_data_log_entry(&da, bp, dep); - dir_hash_update_ftype(hashtab, addr, - ino_ftype); - } - } - } + check_longform_ftype(mp, ip, dep, irec, ino_offset, hashtab, + addr, &da, bp); /* * check easy case first, regular inode, just bump From patchwork Mon May 16 18:11:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 12851325 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48F80C433F5 for ; Mon, 16 May 2022 18:11:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344608AbiEPSLp (ORCPT ); Mon, 16 May 2022 14:11:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242072AbiEPSLh (ORCPT ); Mon, 16 May 2022 14:11:37 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A07C13A1B1 for ; Mon, 16 May 2022 11:11:35 -0700 (PDT) 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 ams.source.kernel.org (Postfix) with ESMTPS id 4BBCBB8149C for ; Mon, 16 May 2022 18:11:34 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EB8C8C385AA; Mon, 16 May 2022 18:11:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1652724693; bh=QQUGK6x0ymbzmKMY1mjabJZN+3Yr3HidOP09Efz13/M=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=sq7Nfkakz5dJxHyz1uV/jViEpEZcWbdTa9wL76BeLDYb/vgzM33FSKDll2BKJe1yN EXanpnT37GgPLwquryQ2BSxq+0ssr2X5vN7Qthujiyo1/eGzj1v+eJGMMOSs88k6dl f3Sao/Dw55/yLGYDAONgvEWRd4HgQV7kwUyb/Pn9Hi44RGfgExm+JrDCxIuJvv2vzL YrbZef7K2jvSDzUzAT8CbKaZrlfmsSl7XcsfaeimqwbDGo6TPRtHD98qW0YTYfHEUx ZCgnkhP+KgjxOQjhnsV+CySXF8iLHfoQZRLnOf0Bia21kWhVpO2jeyU32RoeNs+JdC fEPCATSVw7Smg== Date: Mon, 16 May 2022 11:11:32 -0700 From: "Darrick J. Wong" To: sandeen@sandeen.net, david@fromorbit.com Cc: linux-xfs@vger.kernel.org Subject: [PATCH 4/3] xfs_repair: always rewrite secondary supers when needsrepair is set Message-ID: References: <165176674590.248791.17672675617466150793.stgit@magnolia> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <165176674590.248791.17672675617466150793.stgit@magnolia> Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Dave Chinner complained about xfs_scrub failures coming from xfs/158. That test induces xfs_repair to fail while upgrading a filesystem to have the inobtcount feature, and then restarts xfs_repair to finish the upgrade. When the second xfs_repair run starts, it will find that the primary super has NEEDSREPAIR set, along with whatever new feature that we were trying to add to the filesystem. From there, repair completes the upgrade in much the same manner as the first repair run would have, with one big exception -- it forgets to set features_changed to trigger rewriting of the secondary supers at the end of repair. This results in discrepancies between the supers: # XFS_REPAIR_FAIL_AFTER_PHASE=2 xfs_repair -c inobtcount=1 /dev/sdf Phase 1 - find and verify superblock... Phase 2 - using internal log - zero log... - scan filesystem freespace and inode maps... - found root inode chunk Adding inode btree counts to filesystem. Killed # xfs_repair /dev/sdf Phase 1 - find and verify superblock... Phase 2 - using internal log - zero log... - scan filesystem freespace and inode maps... clearing needsrepair flag and regenerating metadata bad inobt block count 0, saw 1 bad finobt block count 0, saw 1 bad inobt block count 0, saw 1 bad finobt block count 0, saw 1 bad inobt block count 0, saw 1 bad finobt block count 0, saw 1 bad inobt block count 0, saw 1 bad finobt block count 0, saw 1 - found root inode chunk Phase 3 - for each AG... - scan and clear agi unlinked lists... - process known inodes and perform inode discovery... - agno = 0 - agno = 1 - agno = 2 - agno = 3 - process newly discovered inodes... Phase 4 - check for duplicate blocks... - setting up duplicate extent list... - check for inodes claiming duplicate blocks... - agno = 1 - agno = 2 - agno = 0 - agno = 3 Phase 5 - rebuild AG headers and trees... - reset superblock... Phase 6 - check inode connectivity... - resetting contents of realtime bitmap and summary inodes - traversing filesystem ... - traversal finished ... - moving disconnected inodes to lost+found ... Phase 7 - verify and correct link counts... done # xfs_db -c 'sb 0' -c 'print' -c 'sb 1' -c 'print' /dev/sdf | \ egrep '(features_ro_compat|features_incompat)' features_ro_compat = 0xd features_incompat = 0xb features_ro_compat = 0x5 features_incompat = 0xb Curiously, re-running xfs_repair will not trigger any warnings about the featureset mismatch between the primary and secondary supers. xfs_scrub immediately notices, which is what causes xfs/158 to fail. This discrepancy doesn't happen when the upgrade completes successfully in a single repair run, so we need to teach repair to rewrite the secondaries at the end of repair any time needsrepair was set. Reported-by: Dave Chinner Signed-off-by: Darrick J. Wong --- repair/agheader.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/repair/agheader.c b/repair/agheader.c index d8f912f2..7da5641b 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -460,6 +460,14 @@ secondary_sb_whack( else do_warn( _("would clear needsrepair flag and regenerate metadata\n")); + /* + * If needsrepair is set on the primary super, there's + * a possibility that repair crashed during an upgrade. + * Set features_changed to ensure that the secondary + * supers are rewritten with the new feature bits once + * we've finished the upgrade. + */ + features_changed = true; } else { /* * Quietly clear needsrepair on the secondary supers as