diff mbox series

[2/4] xfs_repair: fix crash in reset_rt_metadir_inodes

Message ID 174257453632.474645.11619039334465128305.stgit@frogsfrogsfrogs (mailing list archive)
State New
Headers show
Series [1/4] xfs_repair: don't recreate /quota metadir if there are no quota inodes | expand

Commit Message

Darrick J. Wong March 21, 2025, 4:31 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

I observed that xfs_repair -n segfaults during xfs/812 after corrupting
the /rtgroups metadir inode because mp->m_rtdirip isn't loaded.  Fix the
crash and print a warning about the missing inode.

Cc: <linux-xfs@vger.kernel.org> # v6.13.0
Fixes: 7c541c90fd77a2 ("xfs_repair: support realtime groups")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
 repair/phase6.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Comments

Christoph Hellwig March 23, 2025, 6:34 a.m. UTC | #1
On Fri, Mar 21, 2025 at 09:31:46AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> I observed that xfs_repair -n segfaults during xfs/812 after corrupting
> the /rtgroups metadir inode because mp->m_rtdirip isn't loaded.  Fix the
> crash and print a warning about the missing inode.

Looks good:

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

Patch

diff --git a/repair/phase6.c b/repair/phase6.c
index 2d526dda484293..c16164c171d07d 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -3397,15 +3397,21 @@  reset_rt_metadir_inodes(
 		unload_rtgroup_inodes(mp);
 
 	if (mp->m_sb.sb_rgcount > 0) {
-		if (!no_modify) {
+		if (no_modify) {
+			if (!mp->m_rtdirip)
+				do_warn(_("would recreate realtime metadir\n"));
+		} else {
 			error = -libxfs_rtginode_mkdir_parent(mp);
 			if (error)
 				do_error(_("failed to create realtime metadir (%d)\n"),
 					error);
 		}
-		mark_ino_inuse(mp, mp->m_rtdirip->i_ino, S_IFDIR,
-				mp->m_metadirip->i_ino);
-		mark_ino_metadata(mp, mp->m_rtdirip->i_ino);
+
+		if (mp->m_rtdirip) {
+			mark_ino_inuse(mp, mp->m_rtdirip->i_ino, S_IFDIR,
+					mp->m_metadirip->i_ino);
+			mark_ino_metadata(mp, mp->m_rtdirip->i_ino);
+		}
 	}
 
 	/*