[PATCH 08/25] xfs: scrub the backup superblocks

"Darrick J. Wong" <[email protected]>
Newsgroups gmane.comp.file-systems.xfs.general
Message-ID <[email protected]>
Ensure that the geometry presented in the backup superblocks matches
the primary superblock so that repair can recover the filesystem if
that primary gets corrupted.

Signed-off-by: Darrick J. Wong <[email protected]>
---
 fs/xfs/libxfs/xfs_fs.h |    1 +
 fs/xfs/xfs_scrub.c     |   75 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)


diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 22559ab..8d58061 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -535,6 +535,7 @@ struct xfs_scrub_metadata {
 /*
  * Metadata types and flags for scrub operation.
  */
+#define XFS_SCRUB_TYPE_SB	0	/* superblock */
 #define XFS_SCRUB_TYPE_MAX	0
 
 #define XFS_SCRUB_FLAGS_ALL	0x0	/* no flags yet */
diff --git a/fs/xfs/xfs_scrub.c b/fs/xfs/xfs_scrub.c
index fd24af7..3def216 100644
--- a/fs/xfs/xfs_scrub.c
+++ b/fs/xfs/xfs_scrub.c
@@ -704,6 +704,80 @@ out_badcursor:
 	return error;
 }
 
+/* Metadata scrubbers */
+
+/* Scrub the filesystem superblock. */
+STATIC int
+xfs_scrub_sb(
+	struct xfs_inode		*ip,
+	struct xfs_scrub_metadata	*sm)
+{
+	struct xfs_mount		*mp = ip->i_mount;
+	struct xfs_buf			*bp;
+	struct xfs_sb			sb;
+	xfs_agnumber_t			agno;
+	int				error;
+
+	if (sm->control >= mp->m_sb.sb_agcount || sm->flags)
+		return -EINVAL;
+	agno = sm->control;
+
+	error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
+		  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
+		  XFS_FSS_TO_BB(mp, 1), 0, &bp,
+		  &xfs_sb_buf_ops);
+	if (error)
+		return error;
+
+	if (agno == 0)
+		goto out;
+
+	xfs_sb_from_disk(&sb, XFS_BUF_TO_SBP(bp));
+
+	/* Verify the geometries match. */
+#define XFS_SCRUB_SB_FIELD(fn) \
+		XFS_SCRUB_CHECK(mp, bp, "superblock", \
+		sb.sb_##fn == mp->m_sb.sb_##fn)
+	XFS_SCRUB_SB_FIELD(blocksize);
+	XFS_SCRUB_SB_FIELD(dblocks);
+	XFS_SCRUB_SB_FIELD(rblocks);
+	XFS_SCRUB_SB_FIELD(rextents);
+	XFS_SCRUB_SB_FIELD(logstart);
+	XFS_SCRUB_SB_FIELD(rextsize);
+	XFS_SCRUB_SB_FIELD(agblocks);
+	XFS_SCRUB_SB_FIELD(agcount);
+	XFS_SCRUB_SB_FIELD(rbmblocks);
+	XFS_SCRUB_SB_FIELD(logblocks);
+	XFS_SCRUB_SB_FIELD(sectsize);
+	XFS_SCRUB_SB_FIELD(inodesize);
+#undef XFS_SCRUB_SB_FIELD
+
+#define XFS_SCRUB_SB_FEAT(fn) \
+		XFS_SCRUB_CHECK(mp, bp, "superblock", \
+		xfs_sb_version_has##fn(&sb) == xfs_sb_version_has##fn(&mp->m_sb))
+        XFS_SCRUB_SB_FEAT(align);
+        XFS_SCRUB_SB_FEAT(dalign);
+        XFS_SCRUB_SB_FEAT(logv2);
+        XFS_SCRUB_SB_FEAT(extflgbit);
+        XFS_SCRUB_SB_FEAT(sector);
+        XFS_SCRUB_SB_FEAT(asciici);
+        XFS_SCRUB_SB_FEAT(morebits);
+        XFS_SCRUB_SB_FEAT(lazysbcount);
+        XFS_SCRUB_SB_FEAT(crc);
+        XFS_SCRUB_SB_FEAT(_pquotino);
+        XFS_SCRUB_SB_FEAT(ftype);
+        XFS_SCRUB_SB_FEAT(finobt);
+        XFS_SCRUB_SB_FEAT(sparseinodes);
+        XFS_SCRUB_SB_FEAT(metauuid);
+        XFS_SCRUB_SB_FEAT(rmapbt);
+        XFS_SCRUB_SB_FEAT(reflink);
+#undef XFS_SCRUB_SB_FEAT
+
+out:
+	xfs_buf_relse(bp);
+	return error;
+}
+
 /* Scrubbing dispatch. */
 
 struct xfs_scrub_meta_fns {
@@ -712,6 +786,7 @@ struct xfs_scrub_meta_fns {
 };
 
 static const struct xfs_scrub_meta_fns meta_scrub_fns[] = {
+	{xfs_scrub_sb,		NULL},
 };
 
 /* Dispatch metadata scrubbing. */

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.