Browse Source

xfs: superblock scrub should use short-lived buffers

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>
Darrick J. Wong 7 years ago
parent
commit
689e11c84b
4 changed files with 27 additions and 3 deletions
  1. 22 0
      fs/xfs/libxfs/xfs_sb.c
  2. 3 0
      fs/xfs/libxfs/xfs_sb.h
  3. 1 0
      fs/xfs/libxfs/xfs_shared.h
  4. 1 3
      fs/xfs/scrub/agheader.c

+ 22 - 0
fs/xfs/libxfs/xfs_sb.c

@@ -972,3 +972,25 @@ xfs_fs_geometry(
 
 
 	return 0;
 	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;
+}

+ 3 - 0
fs/xfs/libxfs/xfs_sb.h

@@ -37,5 +37,8 @@ extern void	xfs_sb_quota_from_disk(struct xfs_sb *sbp);
 #define XFS_FS_GEOM_MAX_STRUCT_VER	(4)
 #define XFS_FS_GEOM_MAX_STRUCT_VER	(4)
 extern int	xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo,
 extern int	xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo,
 				int struct_version);
 				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__ */
 #endif	/* __XFS_SB_H__ */

+ 1 - 0
fs/xfs/libxfs/xfs_shared.h

@@ -112,6 +112,7 @@ void	xfs_log_get_max_trans_res(struct xfs_mount *mp,
 #define	XFS_ATTR_BTREE_REF	1
 #define	XFS_ATTR_BTREE_REF	1
 #define	XFS_DQUOT_REF		1
 #define	XFS_DQUOT_REF		1
 #define	XFS_REFC_BTREE_REF	1
 #define	XFS_REFC_BTREE_REF	1
+#define	XFS_SSB_REF		0
 
 
 /*
 /*
  * Flags for xfs_trans_ichgtime().
  * Flags for xfs_trans_ichgtime().

+ 1 - 3
fs/xfs/scrub/agheader.c

@@ -157,9 +157,7 @@ xfs_scrub_superblock(
 	if (agno == 0)
 	if (agno == 0)
 		return 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
 	 * The superblock verifier can return several different error codes
 	 * if it thinks the superblock doesn't look right.  For a mount these
 	 * if it thinks the superblock doesn't look right.  For a mount these