[XFS] factor out xfs_read_agf helper
Add a helper to read the AGF header and perform basic verification. Based on hunks from a larger patch from Dave Chinner. (First sent on Juli 23rd) Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Niv Sardi <xaiki@sgi.com>
This commit is contained in:
committed by
Niv Sardi
parent
5e1be0fb1a
commit
4805621a37
@@ -91,6 +91,8 @@ typedef struct xfs_agf {
|
|||||||
#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
|
#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
|
||||||
#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp))
|
#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp))
|
||||||
|
|
||||||
|
extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp,
|
||||||
|
xfs_agnumber_t agno, int flags, struct xfs_buf **bpp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of the unlinked inode hash table in the agi.
|
* Size of the unlinked inode hash table in the agi.
|
||||||
|
@@ -2233,44 +2233,41 @@ xfs_alloc_put_freelist(
|
|||||||
* Read in the allocation group header (free/alloc section).
|
* Read in the allocation group header (free/alloc section).
|
||||||
*/
|
*/
|
||||||
int /* error */
|
int /* error */
|
||||||
xfs_alloc_read_agf(
|
xfs_read_agf(
|
||||||
xfs_mount_t *mp, /* mount point structure */
|
struct xfs_mount *mp, /* mount point structure */
|
||||||
xfs_trans_t *tp, /* transaction pointer */
|
struct xfs_trans *tp, /* transaction pointer */
|
||||||
xfs_agnumber_t agno, /* allocation group number */
|
xfs_agnumber_t agno, /* allocation group number */
|
||||||
int flags, /* XFS_ALLOC_FLAG_... */
|
int flags, /* XFS_BUF_ */
|
||||||
xfs_buf_t **bpp) /* buffer for the ag freelist header */
|
struct xfs_buf **bpp) /* buffer for the ag freelist header */
|
||||||
{
|
{
|
||||||
xfs_agf_t *agf; /* ag freelist header */
|
struct xfs_agf *agf; /* ag freelist header */
|
||||||
int agf_ok; /* set if agf is consistent */
|
int agf_ok; /* set if agf is consistent */
|
||||||
xfs_buf_t *bp; /* return value */
|
|
||||||
xfs_perag_t *pag; /* per allocation group data */
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ASSERT(agno != NULLAGNUMBER);
|
ASSERT(agno != NULLAGNUMBER);
|
||||||
error = xfs_trans_read_buf(
|
error = xfs_trans_read_buf(
|
||||||
mp, tp, mp->m_ddev_targp,
|
mp, tp, mp->m_ddev_targp,
|
||||||
XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
|
XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
|
||||||
XFS_FSS_TO_BB(mp, 1),
|
XFS_FSS_TO_BB(mp, 1), flags, bpp);
|
||||||
(flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0U,
|
|
||||||
&bp);
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
ASSERT(!bp || !XFS_BUF_GETERROR(bp));
|
if (!*bpp)
|
||||||
if (!bp) {
|
|
||||||
*bpp = NULL;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
ASSERT(!XFS_BUF_GETERROR(*bpp));
|
||||||
|
agf = XFS_BUF_TO_AGF(*bpp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate the magic number of the agf block.
|
* Validate the magic number of the agf block.
|
||||||
*/
|
*/
|
||||||
agf = XFS_BUF_TO_AGF(bp);
|
|
||||||
agf_ok =
|
agf_ok =
|
||||||
be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC &&
|
be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC &&
|
||||||
XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
|
XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
|
||||||
be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
|
be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
|
||||||
be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
|
be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
|
||||||
be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
|
be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) &&
|
||||||
be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp);
|
be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp) &&
|
||||||
|
be32_to_cpu(agf->agf_seqno) == agno;
|
||||||
if (xfs_sb_version_haslazysbcount(&mp->m_sb))
|
if (xfs_sb_version_haslazysbcount(&mp->m_sb))
|
||||||
agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <=
|
agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <=
|
||||||
be32_to_cpu(agf->agf_length);
|
be32_to_cpu(agf->agf_length);
|
||||||
@@ -2278,9 +2275,41 @@ xfs_alloc_read_agf(
|
|||||||
XFS_RANDOM_ALLOC_READ_AGF))) {
|
XFS_RANDOM_ALLOC_READ_AGF))) {
|
||||||
XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
|
XFS_CORRUPTION_ERROR("xfs_alloc_read_agf",
|
||||||
XFS_ERRLEVEL_LOW, mp, agf);
|
XFS_ERRLEVEL_LOW, mp, agf);
|
||||||
xfs_trans_brelse(tp, bp);
|
xfs_trans_brelse(tp, *bpp);
|
||||||
return XFS_ERROR(EFSCORRUPTED);
|
return XFS_ERROR(EFSCORRUPTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read in the allocation group header (free/alloc section).
|
||||||
|
*/
|
||||||
|
int /* error */
|
||||||
|
xfs_alloc_read_agf(
|
||||||
|
struct xfs_mount *mp, /* mount point structure */
|
||||||
|
struct xfs_trans *tp, /* transaction pointer */
|
||||||
|
xfs_agnumber_t agno, /* allocation group number */
|
||||||
|
int flags, /* XFS_ALLOC_FLAG_... */
|
||||||
|
struct xfs_buf **bpp) /* buffer for the ag freelist header */
|
||||||
|
{
|
||||||
|
struct xfs_agf *agf; /* ag freelist header */
|
||||||
|
struct xfs_perag *pag; /* per allocation group data */
|
||||||
|
int error;
|
||||||
|
|
||||||
|
ASSERT(agno != NULLAGNUMBER);
|
||||||
|
|
||||||
|
error = xfs_read_agf(mp, tp, agno,
|
||||||
|
(flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0,
|
||||||
|
bpp);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
if (!*bpp)
|
||||||
|
return 0;
|
||||||
|
ASSERT(!XFS_BUF_GETERROR(*bpp));
|
||||||
|
|
||||||
|
agf = XFS_BUF_TO_AGF(*bpp);
|
||||||
pag = &mp->m_perag[agno];
|
pag = &mp->m_perag[agno];
|
||||||
if (!pag->pagf_init) {
|
if (!pag->pagf_init) {
|
||||||
pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
|
pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
|
||||||
@@ -2308,8 +2337,6 @@ xfs_alloc_read_agf(
|
|||||||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
|
be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGF, XFS_AGF_REF);
|
|
||||||
*bpp = bp;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3970,7 +3970,6 @@ xlog_recover_check_summary(
|
|||||||
xfs_agf_t *agfp;
|
xfs_agf_t *agfp;
|
||||||
xfs_buf_t *agfbp;
|
xfs_buf_t *agfbp;
|
||||||
xfs_buf_t *agibp;
|
xfs_buf_t *agibp;
|
||||||
xfs_daddr_t agfdaddr;
|
|
||||||
xfs_buf_t *sbbp;
|
xfs_buf_t *sbbp;
|
||||||
#ifdef XFS_LOUD_RECOVERY
|
#ifdef XFS_LOUD_RECOVERY
|
||||||
xfs_sb_t *sbp;
|
xfs_sb_t *sbp;
|
||||||
@@ -3987,21 +3986,18 @@ xlog_recover_check_summary(
|
|||||||
itotal = 0LL;
|
itotal = 0LL;
|
||||||
ifree = 0LL;
|
ifree = 0LL;
|
||||||
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
|
for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
|
||||||
agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp));
|
error = xfs_read_agf(mp, NULL, agno, 0, &agfbp);
|
||||||
agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr,
|
if (error) {
|
||||||
XFS_FSS_TO_BB(mp, 1), 0);
|
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||||
if (XFS_BUF_ISERROR(agfbp)) {
|
"xlog_recover_check_summary(agf)"
|
||||||
xfs_ioerror_alert("xlog_recover_check_summary(agf)",
|
"agf read failed agno %d error %d",
|
||||||
mp, agfbp, agfdaddr);
|
agno, error);
|
||||||
|
} else {
|
||||||
|
agfp = XFS_BUF_TO_AGF(agfbp);
|
||||||
|
freeblks += be32_to_cpu(agfp->agf_freeblks) +
|
||||||
|
be32_to_cpu(agfp->agf_flcount);
|
||||||
|
xfs_buf_relse(agfbp);
|
||||||
}
|
}
|
||||||
agfp = XFS_BUF_TO_AGF(agfbp);
|
|
||||||
ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum));
|
|
||||||
ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum)));
|
|
||||||
ASSERT(be32_to_cpu(agfp->agf_seqno) == agno);
|
|
||||||
|
|
||||||
freeblks += be32_to_cpu(agfp->agf_freeblks) +
|
|
||||||
be32_to_cpu(agfp->agf_flcount);
|
|
||||||
xfs_buf_relse(agfbp);
|
|
||||||
|
|
||||||
error = xfs_read_agi(mp, NULL, agno, &agibp);
|
error = xfs_read_agi(mp, NULL, agno, &agibp);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
|
Reference in New Issue
Block a user