aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 445bf1aef31c..a815412eab80 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -200,7 +200,8 @@ xfs_ialloc_inode_init(
200 */ 200 */
201 d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); 201 d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));
202 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, 202 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
203 mp->m_bsize * blks_per_cluster, 0); 203 mp->m_bsize * blks_per_cluster,
204 XBF_UNMAPPED);
204 if (!fbuf) 205 if (!fbuf)
205 return ENOMEM; 206 return ENOMEM;
206 /* 207 /*
@@ -210,6 +211,7 @@ xfs_ialloc_inode_init(
210 * to log a whole cluster of inodes instead of all the 211 * to log a whole cluster of inodes instead of all the
211 * individual transactions causing a lot of log traffic. 212 * individual transactions causing a lot of log traffic.
212 */ 213 */
214 fbuf->b_ops = &xfs_inode_buf_ops;
213 xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog); 215 xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
214 for (i = 0; i < ninodes; i++) { 216 for (i = 0; i < ninodes; i++) {
215 int ioffset = i << mp->m_sb.sb_inodelog; 217 int ioffset = i << mp->m_sb.sb_inodelog;
@@ -250,6 +252,7 @@ xfs_ialloc_ag_alloc(
250 /* boundary */ 252 /* boundary */
251 struct xfs_perag *pag; 253 struct xfs_perag *pag;
252 254
255 memset(&args, 0, sizeof(args));
253 args.tp = tp; 256 args.tp = tp;
254 args.mp = tp->t_mountp; 257 args.mp = tp->t_mountp;
255 258
@@ -876,9 +879,9 @@ error0:
876 * This function is designed to be called twice if it has to do an allocation 879 * This function is designed to be called twice if it has to do an allocation
877 * to make more free inodes. On the first call, *IO_agbp should be set to NULL. 880 * to make more free inodes. On the first call, *IO_agbp should be set to NULL.
878 * If an inode is available without having to performn an allocation, an inode 881 * If an inode is available without having to performn an allocation, an inode
879 * number is returned. In this case, *IO_agbp would be NULL. If an allocation 882 * number is returned. In this case, *IO_agbp is set to NULL. If an allocation
880 * needes to be done, xfs_dialloc would return the current AGI buffer in 883 * needs to be done, xfs_dialloc returns the current AGI buffer in *IO_agbp.
881 * *IO_agbp. The caller should then commit the current transaction, allocate a 884 * The caller should then commit the current transaction, allocate a
882 * new transaction, and call xfs_dialloc() again, passing in the previous value 885 * new transaction, and call xfs_dialloc() again, passing in the previous value
883 * of *IO_agbp. IO_agbp should be held across the transactions. Since the AGI 886 * of *IO_agbp. IO_agbp should be held across the transactions. Since the AGI
884 * buffer is locked across the two calls, the second call is guaranteed to have 887 * buffer is locked across the two calls, the second call is guaranteed to have
@@ -1471,6 +1474,57 @@ xfs_check_agi_unlinked(
1471#define xfs_check_agi_unlinked(agi) 1474#define xfs_check_agi_unlinked(agi)
1472#endif 1475#endif
1473 1476
1477static void
1478xfs_agi_verify(
1479 struct xfs_buf *bp)
1480{
1481 struct xfs_mount *mp = bp->b_target->bt_mount;
1482 struct xfs_agi *agi = XFS_BUF_TO_AGI(bp);
1483 int agi_ok;
1484
1485 /*
1486 * Validate the magic number of the agi block.
1487 */
1488 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1489 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
1490
1491 /*
1492 * during growfs operations, the perag is not fully initialised,
1493 * so we can't use it for any useful checking. growfs ensures we can't
1494 * use it by using uncached buffers that don't have the perag attached
1495 * so we can detect and avoid this problem.
1496 */
1497 if (bp->b_pag)
1498 agi_ok = agi_ok && be32_to_cpu(agi->agi_seqno) ==
1499 bp->b_pag->pag_agno;
1500
1501 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1502 XFS_RANDOM_IALLOC_READ_AGI))) {
1503 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, agi);
1504 xfs_buf_ioerror(bp, EFSCORRUPTED);
1505 }
1506 xfs_check_agi_unlinked(agi);
1507}
1508
1509static void
1510xfs_agi_read_verify(
1511 struct xfs_buf *bp)
1512{
1513 xfs_agi_verify(bp);
1514}
1515
1516static void
1517xfs_agi_write_verify(
1518 struct xfs_buf *bp)
1519{
1520 xfs_agi_verify(bp);
1521}
1522
1523const struct xfs_buf_ops xfs_agi_buf_ops = {
1524 .verify_read = xfs_agi_read_verify,
1525 .verify_write = xfs_agi_write_verify,
1526};
1527
1474/* 1528/*
1475 * Read in the allocation group header (inode allocation section) 1529 * Read in the allocation group header (inode allocation section)
1476 */ 1530 */
@@ -1481,38 +1535,18 @@ xfs_read_agi(
1481 xfs_agnumber_t agno, /* allocation group number */ 1535 xfs_agnumber_t agno, /* allocation group number */
1482 struct xfs_buf **bpp) /* allocation group hdr buf */ 1536 struct xfs_buf **bpp) /* allocation group hdr buf */
1483{ 1537{
1484 struct xfs_agi *agi; /* allocation group header */
1485 int agi_ok; /* agi is consistent */
1486 int error; 1538 int error;
1487 1539
1488 ASSERT(agno != NULLAGNUMBER); 1540 ASSERT(agno != NULLAGNUMBER);
1489 1541
1490 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 1542 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
1491 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 1543 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1492 XFS_FSS_TO_BB(mp, 1), 0, bpp); 1544 XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops);
1493 if (error) 1545 if (error)
1494 return error; 1546 return error;
1495 1547
1496 ASSERT(!xfs_buf_geterror(*bpp)); 1548 ASSERT(!xfs_buf_geterror(*bpp));
1497 agi = XFS_BUF_TO_AGI(*bpp);
1498
1499 /*
1500 * Validate the magic number of the agi block.
1501 */
1502 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1503 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
1504 be32_to_cpu(agi->agi_seqno) == agno;
1505 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1506 XFS_RANDOM_IALLOC_READ_AGI))) {
1507 XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW,
1508 mp, agi);
1509 xfs_trans_brelse(tp, *bpp);
1510 return XFS_ERROR(EFSCORRUPTED);
1511 }
1512
1513 xfs_buf_set_ref(*bpp, XFS_AGI_REF); 1549 xfs_buf_set_ref(*bpp, XFS_AGI_REF);
1514
1515 xfs_check_agi_unlinked(agi);
1516 return 0; 1550 return 0;
1517} 1551}
1518 1552