From: Brian Foster <bfoster@redhat.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH RFC v2 3/3] xfs: detect and warn about finobt blocks with an inobt magic value
Date: Mon, 28 Jan 2019 10:20:34 -0500 [thread overview]
Message-ID: <20190128152034.21080-4-bfoster@redhat.com> (raw)
In-Reply-To: <20190128152034.21080-1-bfoster@redhat.com>
xfs_repair had a bug where finobt reconstruction could create
certain level > 0 nodes with an inobt magic. This went undetected by
kernel verifiers because the inode btree verifiers were common
between the inobt and finobt. Now that the verifiers enforce the
appropriate magic value based on btree type, a mitigation strategy
is necessary to avoid turning a low impact metadata inconsistency
into an immediate and fatal runtime error.
Add an explicit check for a finobt block with an inobt verifier to
the [f]inobt structure verifier function. In the event that this
occurs, report this as a warning rather than a verifier error to
indicate to the user to upgrade xfsprogs and run xfs_repair. Note
that without this change, an affected finobt filesystem will trigger
a verifier error at mount time due to the perag reservation finobt
scan and fail to mount.
Also filter out this error from the lower level btree verification
logic. This logic is what detected the problem in the first place,
but can also cause an otherwise functional filesystem to fail. Note
that while this logic has been around for some time, it hasn't
always been active on non-debug kernels or triggered a runtime
error. This means that the scarcity of error reports is not
necessarily indicative of the prevalence of the problem in the
field.
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/libxfs/xfs_btree.c | 12 ++++++++++--
fs/xfs/libxfs/xfs_ialloc_btree.c | 25 ++++++++++++++++++++++---
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index bbdae2b4559f..6bb5882d69f3 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -132,6 +132,7 @@ __xfs_btree_check_sblock(
struct xfs_mount *mp = cur->bc_mp;
xfs_btnum_t btnum = cur->bc_btnum;
int crc = xfs_sb_version_hascrc(&mp->m_sb);
+ uint32_t magic = xfs_btree_magic(crc, btnum);
if (crc) {
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
@@ -141,8 +142,15 @@ __xfs_btree_check_sblock(
return __this_address;
}
- if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(crc, btnum))
- return __this_address;
+ /*
+ * Exclude the case of a finobt block with inobt magic from being an
+ * error. See the inobt verifier for further details.
+ */
+ if (be32_to_cpu(block->bb_magic) != magic) {
+ if (!(magic == XFS_FIBT_CRC_MAGIC &&
+ (be32_to_cpu(block->bb_magic) == XFS_IBT_CRC_MAGIC)))
+ return __this_address;
+ }
if (be16_to_cpu(block->bb_level) != level)
return __this_address;
if (be16_to_cpu(block->bb_numrecs) >
diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c
index c57ecb6b1255..79aafef42df6 100644
--- a/fs/xfs/libxfs/xfs_ialloc_btree.c
+++ b/fs/xfs/libxfs/xfs_ialloc_btree.c
@@ -259,9 +259,28 @@ xfs_inobt_verify(
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
xfs_failaddr_t fa;
unsigned int level;
+ bool hascrc = xfs_sb_version_hascrc(&mp->m_sb);
- if (!xfs_verify_magic(bp, block->bb_magic))
- return __this_address;
+ /*
+ * xfs_repair had a bug that created interior finobt nodes with inobt
+ * magic values. This escaped verifier detection for some time because
+ * the verifier originally passed so long as the magic matched one of
+ * the several possible [f]inobt magic values.
+ *
+ * We now distinguish between magic values per tree, but we cannot
+ * outright fail as this would cause otherwise working filesystems to
+ * become unusable. Instead, warn the user to upgrade xfs_repair and fix
+ * the problem.
+ */
+ if (!xfs_verify_magic(bp, block->bb_magic)) {
+ if ((bp->b_ops->magic[hascrc] == XFS_FIBT_CRC_MAGIC) &&
+ (block->bb_magic == cpu_to_be32(XFS_IBT_CRC_MAGIC)))
+ xfs_warn(mp,
+"WARNING: inobt magic on finobt block 0x%llx. This is caused by xfs_repair. "
+"Please upgrade xfsprogs, unmount and run xfs_repair.", bp->b_bn);
+ else
+ return __this_address;
+ }
/*
* During growfs operations, we can't verify the exact owner as the
@@ -273,7 +292,7 @@ xfs_inobt_verify(
* but beware of the landmine (i.e. need to check pag->pagi_init) if we
* ever do.
*/
- if (xfs_sb_version_hascrc(&mp->m_sb)) {
+ if (hascrc) {
fa = xfs_btree_sblock_v5hdr_verify(bp);
if (fa)
return fa;
--
2.17.2
prev parent reply other threads:[~2019-01-28 15:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-28 15:20 [PATCH RFC v2 0/3] xfs: fix [f]inobt magic value verification Brian Foster
2019-01-28 15:20 ` [PATCH RFC v2 1/3] xfs: create a separate finobt verifier Brian Foster
2019-01-28 15:20 ` [PATCH RFC v2 2/3] xfs: distinguish between inobt and finobt magic values Brian Foster
2019-01-28 22:54 ` Dave Chinner
2019-01-29 14:01 ` Brian Foster
2019-01-29 21:16 ` Dave Chinner
2019-01-30 1:05 ` Brian Foster
2019-01-30 2:15 ` Dave Chinner
2019-01-30 12:15 ` Brian Foster
2019-01-28 15:20 ` Brian Foster [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190128152034.21080-4-bfoster@redhat.com \
--to=bfoster@redhat.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.