aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-12 06:54:05 -0500
committerBen Myers <bpm@sgi.com>2012-11-15 22:34:12 -0500
commit3702ce6ed71cd60451ab278088863456dcb0dd99 (patch)
treee7d4932f04525d0aeca38a4d7a88b628c34cd15e /fs/xfs
parent5d5f527d13369d0047d52b7ac4ddee4f8c0ad173 (diff)
xfs: verify AGI blocks as they are read from disk
Add an AGI block verify callback function and pass it into the buffer read functions. Remove the now redundant verification code that is currently in use. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_ialloc.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 12e3dead439d..5bd255e5f7b8 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -1472,6 +1472,40 @@ xfs_check_agi_unlinked(
1472#define xfs_check_agi_unlinked(agi) 1472#define xfs_check_agi_unlinked(agi)
1473#endif 1473#endif
1474 1474
1475static void
1476xfs_agi_read_verify(
1477 struct xfs_buf *bp)
1478{
1479 struct xfs_mount *mp = bp->b_target->bt_mount;
1480 struct xfs_agi *agi = XFS_BUF_TO_AGI(bp);
1481 int agi_ok;
1482
1483 /*
1484 * Validate the magic number of the agi block.
1485 */
1486 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1487 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
1488
1489 /*
1490 * during growfs operations, the perag is not fully initialised,
1491 * so we can't use it for any useful checking. growfs ensures we can't
1492 * use it by using uncached buffers that don't have the perag attached
1493 * so we can detect and avoid this problem.
1494 */
1495 if (bp->b_pag)
1496 agi_ok = agi_ok && be32_to_cpu(agi->agi_seqno) ==
1497 bp->b_pag->pag_agno;
1498
1499 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1500 XFS_RANDOM_IALLOC_READ_AGI))) {
1501 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, agi);
1502 xfs_buf_ioerror(bp, EFSCORRUPTED);
1503 }
1504 xfs_check_agi_unlinked(agi);
1505 bp->b_iodone = NULL;
1506 xfs_buf_ioend(bp, 0);
1507}
1508
1475/* 1509/*
1476 * Read in the allocation group header (inode allocation section) 1510 * Read in the allocation group header (inode allocation section)
1477 */ 1511 */
@@ -1482,38 +1516,18 @@ xfs_read_agi(
1482 xfs_agnumber_t agno, /* allocation group number */ 1516 xfs_agnumber_t agno, /* allocation group number */
1483 struct xfs_buf **bpp) /* allocation group hdr buf */ 1517 struct xfs_buf **bpp) /* allocation group hdr buf */
1484{ 1518{
1485 struct xfs_agi *agi; /* allocation group header */
1486 int agi_ok; /* agi is consistent */
1487 int error; 1519 int error;
1488 1520
1489 ASSERT(agno != NULLAGNUMBER); 1521 ASSERT(agno != NULLAGNUMBER);
1490 1522
1491 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 1523 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
1492 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 1524 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1493 XFS_FSS_TO_BB(mp, 1), 0, bpp, NULL); 1525 XFS_FSS_TO_BB(mp, 1), 0, bpp, xfs_agi_read_verify);
1494 if (error) 1526 if (error)
1495 return error; 1527 return error;
1496 1528
1497 ASSERT(!xfs_buf_geterror(*bpp)); 1529 ASSERT(!xfs_buf_geterror(*bpp));
1498 agi = XFS_BUF_TO_AGI(*bpp);
1499
1500 /*
1501 * Validate the magic number of the agi block.
1502 */
1503 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1504 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
1505 be32_to_cpu(agi->agi_seqno) == agno;
1506 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1507 XFS_RANDOM_IALLOC_READ_AGI))) {
1508 XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW,
1509 mp, agi);
1510 xfs_trans_brelse(tp, *bpp);
1511 return XFS_ERROR(EFSCORRUPTED);
1512 }
1513
1514 xfs_buf_set_ref(*bpp, XFS_AGI_REF); 1530 xfs_buf_set_ref(*bpp, XFS_AGI_REF);
1515
1516 xfs_check_agi_unlinked(agi);
1517 return 0; 1531 return 0;
1518} 1532}
1519 1533