File xfsprogs-xfs_repair-check-plausibility-of-root-dir-pointer-be.patch of Package xfsprogs.21555
From ded6b55889acf0edf0a8e12744cc05a6d4677e29 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.wong@oracle.com>
Date: Thu, 27 Feb 2020 15:05:47 -0500
Subject: [PATCH] xfs_repair: check plausibility of root dir pointer before
trashing it
Git-commit: ded6b55889acf0edf0a8e12744cc05a6d4677e29
Patch-mainline: v5.5.0-rc1
References: bsc#1188651
If sb_rootino doesn't point to where we think mkfs should have allocated
the root directory, check to see if the alleged root directory actually
looks like a root directory. If so, we'll let it live because someone
could have changed sunit since formatting time, and that changes the
root directory inode estimate.
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>
Acked-by: Anthony Iliopoulos <ailiop@suse.com>
---
repair/xfs_repair.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 0e24bdd5ba93..c6237453c9b9 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -426,6 +426,37 @@ _("would reset superblock %s inode pointer to %"PRIu64"\n"),
*ino = expected_ino;
}
+/* Does the root directory inode look like a plausible root directory? */
+static bool
+has_plausible_rootdir(
+ struct xfs_mount *mp)
+{
+ struct xfs_inode *ip;
+ xfs_ino_t ino;
+ int error;
+ bool ret = false;
+
+ error = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &ip,
+ &xfs_default_ifork_ops);
+ if (error)
+ goto out;
+ if (!S_ISDIR(VFS_I(ip)->i_mode))
+ goto out_rele;
+
+ error = -libxfs_dir_lookup(NULL, ip, &xfs_name_dotdot, &ino, NULL);
+ if (error)
+ goto out_rele;
+
+ /* The root directory '..' entry points to the directory. */
+ if (ino == mp->m_sb.sb_rootino)
+ ret = true;
+
+out_rele:
+ IRELE(ip);
+out:
+ return ret;
+}
+
static void
calc_mkfs(xfs_mount_t *mp)
{
@@ -499,6 +530,21 @@ calc_mkfs(xfs_mount_t *mp)
else
last_prealloc_ino = XFS_OFFBNO_TO_AGINO(mp, fino_bno + 1, 0);
+ /*
+ * If the root inode isn't where we think it is, check its plausibility
+ * as a root directory. It's possible that somebody changed sunit
+ * since the filesystem was created, which can change the value of the
+ * above computation. Don't blow up the root directory if this is the
+ * case.
+ */
+ if (mp->m_sb.sb_rootino != first_prealloc_ino &&
+ has_plausible_rootdir(mp)) {
+ do_warn(
+_("sb root inode value %" PRIu64 " valid but in unaligned location (expected %"PRIu32") possibly due to sunit change\n"),
+ mp->m_sb.sb_rootino, first_prealloc_ino);
+ first_prealloc_ino = mp->m_sb.sb_rootino;
+ }
+
/*
* now the first 3 inodes in the system
*/
--
2.32.0