diff mbox series

[14/16] xfs_repair: complain about free space only seen by one btree

Message ID 158904188639.982941.5408652247371014933.stgit@magnolia (mailing list archive)
State Superseded
Headers show
Series xfs_repair: catch things that xfs_check misses | expand

Commit Message

Darrick J. Wong May 9, 2020, 4:31 p.m. UTC
From: Darrick J. Wong <darrick.wong@oracle.com>

During the free space btree walk, scan_allocbt claims in a comment that
we'll catch FREE1 blocks (i.e. blocks that were seen by only one free
space btree) later.  This never happens, with the result that xfs_repair
in dry-run mode can return 0 on a filesystem with corrupt free space
btrees.

Found by fuzzing xfs/358 with numrecs = middlebit (or sub).

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 repair/phase4.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Christoph Hellwig May 10, 2020, 7:26 a.m. UTC | #1
On Sat, May 09, 2020 at 09:31:26AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> During the free space btree walk, scan_allocbt claims in a comment that
> we'll catch FREE1 blocks (i.e. blocks that were seen by only one free
> space btree) later.  This never happens, with the result that xfs_repair
> in dry-run mode can return 0 on a filesystem with corrupt free space
> btrees.
> 
> Found by fuzzing xfs/358 with numrecs = middlebit (or sub).
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>
diff mbox series

Patch

diff --git a/repair/phase4.c b/repair/phase4.c
index 8197db06..a43413c7 100644
--- a/repair/phase4.c
+++ b/repair/phase4.c
@@ -306,6 +306,12 @@  phase4(xfs_mount_t *mp)
 		for (j = ag_hdr_block; j < ag_end; j += blen)  {
 			bstate = get_bmap_ext(i, j, ag_end, &blen);
 			switch (bstate) {
+			case XR_E_FREE1:
+				if (no_modify)
+					do_warn(
+	_("free space (%u,%u-%u) only seen by one free space btree\n"),
+						i, j, j + blen - 1);
+				break;
 			case XR_E_BAD_STATE:
 			default:
 				do_warn(
@@ -313,7 +319,6 @@  phase4(xfs_mount_t *mp)
 					i, j);
 				/* fall through .. */
 			case XR_E_UNKNOWN:
-			case XR_E_FREE1:
 			case XR_E_FREE:
 			case XR_E_INUSE:
 			case XR_E_INUSE_FS: