xfsprogs/0007-xfs_repair-fix-missing-dir-buffer-corruption-checks.patch
lightmouse 24b4ee7dcb backport bugfix patches from community
Author:    wuguanghao <wuguanghao3@huawei.com>
Date:      Mon Mar 14 20:12:17 2022 +0800
(cherry picked from commit feb7ea39582af46f13599e1678473c98965b05c7)
2022-05-31 16:16:28 +08:00

125 lines
3.9 KiB
Diff

From be752639294c8a1eb0f06275e77744f32e5bd277 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Fri, 10 Jul 2020 15:34:36 -0400
Subject: [PATCH] xfs_repair: fix missing dir buffer corruption checks
The da_read_buf() function operates in "salvage" mode, which means that
if the verifiers fail, it will return a buffer with b_error set. The
callers of da_read_buf, however, do not adequately check for verifier
errors, which means that repair can fail to flag a corrupt filesystem.
Fix the callers to do this properly. The dabtree block walker and the
dabtree path checker functions to complain any time the da node / leafn
verifiers fail. Fix the directory block walking functions to complain
about EFSCORRUPTED, since they already dealt with EFSBADCRC.
Found by running xfs/496 against lhdr.stale = middlebit.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
---
repair/da_util.c | 25 ++++++++++++++++---------
repair/dir2.c | 21 +++++++++++++++++++++
2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/repair/da_util.c b/repair/da_util.c
index 5061880f..7239c2e2 100644
--- a/repair/da_util.c
+++ b/repair/da_util.c
@@ -134,6 +134,15 @@ _("can't read %s block %u for inode %" PRIu64 "\n"),
goto error_out;
}
+ /* corrupt leafn/node; rebuild the dir. */
+ if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
+ do_warn(
+_("corrupt %s tree block %u for inode %" PRIu64 "\n"),
+ FORKNAME(whichfork), bno, da_cursor->ino);
+ libxfs_buf_relse(bp);
+ goto error_out;
+ }
+
node = bp->b_addr;
libxfs_da3_node_hdr_from_disk(mp, &nodehdr, node);
@@ -160,15 +169,6 @@ _("bad %s magic number 0x%x in inode %" PRIu64 " bno = %u\n"),
goto error_out;
}
- /* corrupt node; rebuild the dir. */
- if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
- libxfs_buf_relse(bp);
- do_warn(
-_("corrupt %s tree block %u for inode %" PRIu64 "\n"),
- FORKNAME(whichfork), bno, da_cursor->ino);
- goto error_out;
- }
-
if (nodehdr.count > geo->node_ents) {
do_warn(
_("bad %s record count in inode %" PRIu64 ", count = %d, max = %d\n"),
@@ -562,6 +562,13 @@ _("can't read %s block %u for inode %" PRIu64 "\n"),
FORKNAME(whichfork), dabno, cursor->ino);
return 1;
}
+ if (bp->b_error == -EFSCORRUPTED || bp->b_error == -EFSBADCRC) {
+ do_warn(
+_("corrupt %s tree block %u for inode %" PRIu64 "\n"),
+ FORKNAME(whichfork), dabno, cursor->ino);
+ libxfs_buf_relse(bp);
+ return 1;
+ }
newnode = bp->b_addr;
libxfs_da3_node_hdr_from_disk(mp, &nodehdr, newnode);
diff --git a/repair/dir2.c b/repair/dir2.c
index cbbce601..b374bc7b 100644
--- a/repair/dir2.c
+++ b/repair/dir2.c
@@ -983,6 +983,13 @@ _("can't read block %u for directory inode %" PRIu64 "\n"),
mp->m_dir_geo->datablk, ino);
return 1;
}
+ if (bp->b_error == -EFSCORRUPTED) {
+ do_warn(
+_("corrupt directory block %u for inode %" PRIu64 "\n"),
+ mp->m_dir_geo->datablk, ino);
+ libxfs_buf_relse(bp);
+ return 1;
+ }
/*
* Verify the block
*/
@@ -1122,6 +1129,13 @@ _("can't read file block %u for directory inode %" PRIu64 "\n"),
da_bno, ino);
goto error_out;
}
+ if (bp->b_error == -EFSCORRUPTED) {
+ do_warn(
+_("corrupt directory leafn block %u for inode %" PRIu64 "\n"),
+ da_bno, ino);
+ libxfs_buf_relse(bp);
+ goto error_out;
+ }
leaf = bp->b_addr;
libxfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
/*
@@ -1324,6 +1338,13 @@ _("can't read block %" PRIu64 " for directory inode %" PRIu64 "\n"),
dbno, ino);
continue;
}
+ if (bp->b_error == -EFSCORRUPTED) {
+ do_warn(
+_("corrupt directory data block %lu for inode %" PRIu64 "\n"),
+ dbno, ino);
+ libxfs_buf_relse(bp);
+ continue;
+ }
data = bp->b_addr;
if (!(be32_to_cpu(data->magic) == XFS_DIR2_DATA_MAGIC ||
be32_to_cpu(data->magic) == XFS_DIR3_DATA_MAGIC))
--
2.27.0