[PATCH 2/6] mkfs: check root inode location

Darrick J. Wong
2019-12-04T17:04:43Z

From: Darrick J. Wong <darrick.wong@oracle.com>

Make sure the root inode gets created where repair thinks it should be
created.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
libxfs/libxfs_api_defs.h | 1 +
mkfs/xfs_mkfs.c | 39 +++++++++++++++++++++++++++++++++------
2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 645c9b1b..f8e7d82d 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -156,5 +156,6 @@

#define xfs_ag_init_headers libxfs_ag_init_headers
#define xfs_buf_delwri_submit libxfs_buf_delwri_submit
+#define xfs_ialloc_calc_rootino libxfs_ialloc_calc_rootino

#endif /* __LIBXFS_API_DEFS_H__ */
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 18338a61..71be033d 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3521,6 +3521,38 @@ rewrite_secondary_superblocks(
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
}

+static void
+check_root_ino(
+ struct xfs_mount *mp)
+{
+ xfs_ino_t ino;
+
+ if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
+ fprintf(stderr,
+ _("%s: root inode created in AG %u, not AG 0\n"),
+ progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
+ exit(1);
+ }
+
+ /*
+ * The superblock points to the root directory inode, but xfs_repair
+ * expects to find the root inode in a very specific location computed
+ * from the filesystem geometry for an extra level of verification.
+ *
+ * Fail the format immediately if those assumptions ever break, because
+ * repair will toss the root directory.
+ */
+ ino = libxfs_ialloc_calc_rootino(mp, -1);
+ if (mp->m_sb.sb_rootino != ino) {
+ fprintf(stderr,
+ _("%s: root inode (%llu) not allocated in expected location (%llu)\n"),
+ progname,
+ (unsigned long long)mp->m_sb.sb_rootino,
+ (unsigned long long)ino);
+ exit(1);
+ }
+}
+
int
main(
int argc,
@@ -3807,12 +3839,7 @@ main(
/*
* Protect ourselves against possible stupidity
*/
- if (XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino) != 0) {
- fprintf(stderr,
- _("%s: root inode created in AG %u, not AG 0\n"),
- progname, XFS_INO_TO_AGNO(mp, mp->m_sb.sb_rootino));
- exit(1);
- }
+ check_root_ino(mp);

/*
* Re-write multiple secondary superblocks with rootinode field set