xfs
[Top] [All Lists]

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

To: david@xxxxxxxxxxxxx, darrick.wong@xxxxxxxxxx
Subject: [PATCH 08/25] xfs: scrub the backup superblocks
From: "Darrick J. Wong" <darrick.wong@xxxxxxxxxx>
Date: Thu, 25 Aug 2016 16:41:03 -0700
Cc: linux-xfs@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <147216841262.3108.10746252464845687338.stgit@xxxxxxxxxxxxxxxx>
References: <147216841262.3108.10746252464845687338.stgit@xxxxxxxxxxxxxxxx>
User-agent: StGit/0.17.1-dirty
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 <darrick.wong@xxxxxxxxxx>
---
 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. */

<Prev in Thread] Current Thread [Next in Thread>