xfs: superblock scrub should use short-lived buffers
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 14 May 2018 13:34:31 +0000 (06:34 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 16 May 2018 00:57:05 +0000 (17:57 -0700)
Secondary superblocks are rarely used, so create a helper to read a
given non-primary AG's superblock and ensure that it won't stick around
hogging memory.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_sb.h
fs/xfs/libxfs/xfs_shared.h
fs/xfs/scrub/agheader.c

index d9b94bd..d9bef41 100644 (file)
@@ -972,3 +972,25 @@ xfs_fs_geometry(
 
        return 0;
 }
+
+/* Read a secondary superblock. */
+int
+xfs_sb_read_secondary(
+       struct xfs_mount        *mp,
+       struct xfs_trans        *tp,
+       xfs_agnumber_t          agno,
+       struct xfs_buf          **bpp)
+{
+       struct xfs_buf          *bp;
+       int                     error;
+
+       ASSERT(agno != 0 && agno != NULLAGNUMBER);
+       error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+                       XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
+                       XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops);
+       if (error)
+               return error;
+       xfs_buf_set_ref(bp, XFS_SSB_REF);
+       *bpp = bp;
+       return 0;
+}
index 63dcd2a..5166d78 100644 (file)
@@ -37,5 +37,8 @@ extern void   xfs_sb_quota_from_disk(struct xfs_sb *sbp);
 #define XFS_FS_GEOM_MAX_STRUCT_VER     (4)
 extern int     xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo,
                                int struct_version);
+extern int     xfs_sb_read_secondary(struct xfs_mount *mp,
+                               struct xfs_trans *tp, xfs_agnumber_t agno,
+                               struct xfs_buf **bpp);
 
 #endif /* __XFS_SB_H__ */
index 8efc06e..ae99c26 100644 (file)
@@ -112,6 +112,7 @@ void        xfs_log_get_max_trans_res(struct xfs_mount *mp,
 #define        XFS_ATTR_BTREE_REF      1
 #define        XFS_DQUOT_REF           1
 #define        XFS_REFC_BTREE_REF      1
+#define        XFS_SSB_REF             0
 
 /*
  * Flags for xfs_trans_ichgtime().
index 08a1f01..831acc0 100644 (file)
@@ -157,9 +157,7 @@ xfs_scrub_superblock(
        if (agno == 0)
                return 0;
 
-       error = xfs_trans_read_buf(mp, sc->tp, 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);
+       error = xfs_sb_read_secondary(mp, sc->tp, agno, &bp);
        /*
         * The superblock verifier can return several different error codes
         * if it thinks the superblock doesn't look right.  For a mount these