aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-05-14 09:34:31 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-05-15 20:57:05 -0400
commit689e11c84b15866619e7582486acacaf79d7e3e2 (patch)
tree9d27a9b8ed45ea0603bd7f7bd205d2d4855d178c
parent8389f3ffa22a119b37dc7c2217cd2862bb2ed9da (diff)
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>
-rw-r--r--fs/xfs/libxfs/xfs_sb.c22
-rw-r--r--fs/xfs/libxfs/xfs_sb.h3
-rw-r--r--fs/xfs/libxfs/xfs_shared.h1
-rw-r--r--fs/xfs/scrub/agheader.c4
4 files changed, 27 insertions, 3 deletions
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index d9b94bd5f689..d9bef41a3f26 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -972,3 +972,25 @@ xfs_fs_geometry(
972 972
973 return 0; 973 return 0;
974} 974}
975
976/* Read a secondary superblock. */
977int
978xfs_sb_read_secondary(
979 struct xfs_mount *mp,
980 struct xfs_trans *tp,
981 xfs_agnumber_t agno,
982 struct xfs_buf **bpp)
983{
984 struct xfs_buf *bp;
985 int error;
986
987 ASSERT(agno != 0 && agno != NULLAGNUMBER);
988 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
989 XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
990 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops);
991 if (error)
992 return error;
993 xfs_buf_set_ref(bp, XFS_SSB_REF);
994 *bpp = bp;
995 return 0;
996}
diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h
index 63dcd2a1a657..5166d78b2c34 100644
--- a/fs/xfs/libxfs/xfs_sb.h
+++ b/fs/xfs/libxfs/xfs_sb.h
@@ -37,5 +37,8 @@ extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp);
37#define XFS_FS_GEOM_MAX_STRUCT_VER (4) 37#define XFS_FS_GEOM_MAX_STRUCT_VER (4)
38extern int xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo, 38extern int xfs_fs_geometry(struct xfs_sb *sbp, struct xfs_fsop_geom *geo,
39 int struct_version); 39 int struct_version);
40extern int xfs_sb_read_secondary(struct xfs_mount *mp,
41 struct xfs_trans *tp, xfs_agnumber_t agno,
42 struct xfs_buf **bpp);
40 43
41#endif /* __XFS_SB_H__ */ 44#endif /* __XFS_SB_H__ */
diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h
index 8efc06e62b13..ae99c260adb1 100644
--- a/fs/xfs/libxfs/xfs_shared.h
+++ b/fs/xfs/libxfs/xfs_shared.h
@@ -112,6 +112,7 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
112#define XFS_ATTR_BTREE_REF 1 112#define XFS_ATTR_BTREE_REF 1
113#define XFS_DQUOT_REF 1 113#define XFS_DQUOT_REF 1
114#define XFS_REFC_BTREE_REF 1 114#define XFS_REFC_BTREE_REF 1
115#define XFS_SSB_REF 0
115 116
116/* 117/*
117 * Flags for xfs_trans_ichgtime(). 118 * Flags for xfs_trans_ichgtime().
diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c
index 08a1f013d92c..831acc0a328f 100644
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -157,9 +157,7 @@ xfs_scrub_superblock(
157 if (agno == 0) 157 if (agno == 0)
158 return 0; 158 return 0;
159 159
160 error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp, 160 error = xfs_sb_read_secondary(mp, sc->tp, agno, &bp);
161 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
162 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops);
163 /* 161 /*
164 * The superblock verifier can return several different error codes 162 * The superblock verifier can return several different error codes
165 * if it thinks the superblock doesn't look right. For a mount these 163 * if it thinks the superblock doesn't look right. For a mount these