aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-11-27 22:23:37 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:37:15 -0500
commit5e1be0fb1a3950597aeda448698e85b0595a2e92 (patch)
treee9cb423d6f253b689a9e0cfb4a1d429de37959cd /fs/xfs/xfs_ialloc.c
parent26c5295135d10fc90cbf160adfda392d91f58279 (diff)
[XFS] factor out xfs_read_agi helper
Add a helper to read the AGI 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>
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c101
1 files changed, 63 insertions, 38 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index c8a56c529642..efb65fea203c 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -1462,70 +1462,95 @@ xfs_ialloc_log_agi(
1462 xfs_trans_log_buf(tp, bp, first, last); 1462 xfs_trans_log_buf(tp, bp, first, last);
1463} 1463}
1464 1464
1465#ifdef DEBUG
1466STATIC void
1467xfs_check_agi_unlinked(
1468 struct xfs_agi *agi)
1469{
1470 int i;
1471
1472 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
1473 ASSERT(agi->agi_unlinked[i]);
1474}
1475#else
1476#define xfs_check_agi_unlinked(agi)
1477#endif
1478
1465/* 1479/*
1466 * Read in the allocation group header (inode allocation section) 1480 * Read in the allocation group header (inode allocation section)
1467 */ 1481 */
1468int 1482int
1469xfs_ialloc_read_agi( 1483xfs_read_agi(
1470 xfs_mount_t *mp, /* file system mount structure */ 1484 struct xfs_mount *mp, /* file system mount structure */
1471 xfs_trans_t *tp, /* transaction pointer */ 1485 struct xfs_trans *tp, /* transaction pointer */
1472 xfs_agnumber_t agno, /* allocation group number */ 1486 xfs_agnumber_t agno, /* allocation group number */
1473 xfs_buf_t **bpp) /* allocation group hdr buf */ 1487 struct xfs_buf **bpp) /* allocation group hdr buf */
1474{ 1488{
1475 xfs_agi_t *agi; /* allocation group header */ 1489 struct xfs_agi *agi; /* allocation group header */
1476 int agi_ok; /* agi is consistent */ 1490 int agi_ok; /* agi is consistent */
1477 xfs_buf_t *bp; /* allocation group hdr buf */ 1491 int error;
1478 xfs_perag_t *pag; /* per allocation group data */
1479 int error;
1480 1492
1481 ASSERT(agno != NULLAGNUMBER); 1493 ASSERT(agno != NULLAGNUMBER);
1482 error = xfs_trans_read_buf( 1494
1483 mp, tp, mp->m_ddev_targp, 1495 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
1484 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 1496 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1485 XFS_FSS_TO_BB(mp, 1), 0, &bp); 1497 XFS_FSS_TO_BB(mp, 1), 0, bpp);
1486 if (error) 1498 if (error)
1487 return error; 1499 return error;
1488 ASSERT(bp && !XFS_BUF_GETERROR(bp)); 1500
1501 ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp));
1502 agi = XFS_BUF_TO_AGI(*bpp);
1489 1503
1490 /* 1504 /*
1491 * Validate the magic number of the agi block. 1505 * Validate the magic number of the agi block.
1492 */ 1506 */
1493 agi = XFS_BUF_TO_AGI(bp); 1507 agi_ok = be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
1494 agi_ok = 1508 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
1495 be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && 1509 be32_to_cpu(agi->agi_seqno) == agno;
1496 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
1497 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, 1510 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1498 XFS_RANDOM_IALLOC_READ_AGI))) { 1511 XFS_RANDOM_IALLOC_READ_AGI))) {
1499 XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW, 1512 XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW,
1500 mp, agi); 1513 mp, agi);
1501 xfs_trans_brelse(tp, bp); 1514 xfs_trans_brelse(tp, *bpp);
1502 return XFS_ERROR(EFSCORRUPTED); 1515 return XFS_ERROR(EFSCORRUPTED);
1503 } 1516 }
1517
1518 XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGI, XFS_AGI_REF);
1519
1520 xfs_check_agi_unlinked(agi);
1521 return 0;
1522}
1523
1524int
1525xfs_ialloc_read_agi(
1526 struct xfs_mount *mp, /* file system mount structure */
1527 struct xfs_trans *tp, /* transaction pointer */
1528 xfs_agnumber_t agno, /* allocation group number */
1529 struct xfs_buf **bpp) /* allocation group hdr buf */
1530{
1531 struct xfs_agi *agi; /* allocation group header */
1532 struct xfs_perag *pag; /* per allocation group data */
1533 int error;
1534
1535 error = xfs_read_agi(mp, tp, agno, bpp);
1536 if (error)
1537 return error;
1538
1539 agi = XFS_BUF_TO_AGI(*bpp);
1504 pag = &mp->m_perag[agno]; 1540 pag = &mp->m_perag[agno];
1541
1505 if (!pag->pagi_init) { 1542 if (!pag->pagi_init) {
1506 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); 1543 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
1507 pag->pagi_count = be32_to_cpu(agi->agi_count); 1544 pag->pagi_count = be32_to_cpu(agi->agi_count);
1508 pag->pagi_init = 1; 1545 pag->pagi_init = 1;
1509 } else {
1510 /*
1511 * It's possible for these to be out of sync if
1512 * we are in the middle of a forced shutdown.
1513 */
1514 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
1515 XFS_FORCED_SHUTDOWN(mp));
1516 }
1517
1518#ifdef DEBUG
1519 {
1520 int i;
1521
1522 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
1523 ASSERT(agi->agi_unlinked[i]);
1524 } 1546 }
1525#endif
1526 1547
1527 XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGI, XFS_AGI_REF); 1548 /*
1528 *bpp = bp; 1549 * It's possible for these to be out of sync if
1550 * we are in the middle of a forced shutdown.
1551 */
1552 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
1553 XFS_FORCED_SHUTDOWN(mp));
1529 return 0; 1554 return 0;
1530} 1555}
1531 1556