aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-04-24 02:00:53 -0400
committerDave Chinner <david@fromorbit.com>2014-04-24 02:00:53 -0400
commit2b64ee5cdc106704b5c0f8954a52aa598eee25eb (patch)
tree680de9fa15c6429682d97ca0b1727194d7040d9f /fs/xfs/xfs_ialloc.c
parent6dd8638e4e8764e0d6557fc62840a815a99c136d (diff)
xfs: refactor xfs_difree() inobt bits into xfs_difree_inobt() helper
Refactor xfs_difree() in preparation for the finobt. xfs_difree() performs the validity checks against the ag and reads the agi header. The work of physically updating the inode allocation btree is pushed down into the new xfs_difree_inobt() helper. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c161
1 files changed, 96 insertions, 65 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ab3540b675d5..0283e98a8130 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -1430,74 +1430,30 @@ out_error:
1430 return XFS_ERROR(error); 1430 return XFS_ERROR(error);
1431} 1431}
1432 1432
1433/* 1433STATIC int
1434 * Free disk inode. Carefully avoids touching the incore inode, all 1434xfs_difree_inobt(
1435 * manipulations incore are the caller's responsibility. 1435 struct xfs_mount *mp,
1436 * The on-disk inode is not changed by this operation, only the 1436 struct xfs_trans *tp,
1437 * btree (free inode mask) is changed. 1437 struct xfs_buf *agbp,
1438 */ 1438 xfs_agino_t agino,
1439int 1439 struct xfs_bmap_free *flist,
1440xfs_difree( 1440 int *delete,
1441 xfs_trans_t *tp, /* transaction pointer */ 1441 xfs_ino_t *first_ino,
1442 xfs_ino_t inode, /* inode to be freed */ 1442 struct xfs_inobt_rec_incore *orec)
1443 xfs_bmap_free_t *flist, /* extents to free */
1444 int *delete, /* set if inode cluster was deleted */
1445 xfs_ino_t *first_ino) /* first inode in deleted cluster */
1446{ 1443{
1447 /* REFERENCED */ 1444 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1448 xfs_agblock_t agbno; /* block number containing inode */ 1445 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1449 xfs_buf_t *agbp; /* buffer containing allocation group header */ 1446 struct xfs_perag *pag;
1450 xfs_agino_t agino; /* inode number relative to allocation group */ 1447 struct xfs_btree_cur *cur;
1451 xfs_agnumber_t agno; /* allocation group number */ 1448 struct xfs_inobt_rec_incore rec;
1452 xfs_agi_t *agi; /* allocation group header */ 1449 int ilen;
1453 xfs_btree_cur_t *cur; /* inode btree cursor */ 1450 int error;
1454 int error; /* error return value */ 1451 int i;
1455 int i; /* result code */ 1452 int off;
1456 int ilen; /* inodes in an inode cluster */
1457 xfs_mount_t *mp; /* mount structure for filesystem */
1458 int off; /* offset of inode in inode chunk */
1459 xfs_inobt_rec_incore_t rec; /* btree record */
1460 struct xfs_perag *pag;
1461
1462 mp = tp->t_mountp;
1463 1453
1464 /*
1465 * Break up inode number into its components.
1466 */
1467 agno = XFS_INO_TO_AGNO(mp, inode);
1468 if (agno >= mp->m_sb.sb_agcount) {
1469 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
1470 __func__, agno, mp->m_sb.sb_agcount);
1471 ASSERT(0);
1472 return XFS_ERROR(EINVAL);
1473 }
1474 agino = XFS_INO_TO_AGINO(mp, inode);
1475 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1476 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
1477 __func__, (unsigned long long)inode,
1478 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
1479 ASSERT(0);
1480 return XFS_ERROR(EINVAL);
1481 }
1482 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1483 if (agbno >= mp->m_sb.sb_agblocks) {
1484 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
1485 __func__, agbno, mp->m_sb.sb_agblocks);
1486 ASSERT(0);
1487 return XFS_ERROR(EINVAL);
1488 }
1489 /*
1490 * Get the allocation group header.
1491 */
1492 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1493 if (error) {
1494 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
1495 __func__, error);
1496 return error;
1497 }
1498 agi = XFS_BUF_TO_AGI(agbp);
1499 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); 1454 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1500 ASSERT(agbno < be32_to_cpu(agi->agi_length)); 1455 ASSERT(XFS_AGINO_TO_AGBNO(mp, agino) < be32_to_cpu(agi->agi_length));
1456
1501 /* 1457 /*
1502 * Initialize the cursor. 1458 * Initialize the cursor.
1503 */ 1459 */
@@ -1593,6 +1549,7 @@ xfs_difree(
1593 if (error) 1549 if (error)
1594 goto error0; 1550 goto error0;
1595 1551
1552 *orec = rec;
1596 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1553 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1597 return 0; 1554 return 0;
1598 1555
@@ -1601,6 +1558,80 @@ error0:
1601 return error; 1558 return error;
1602} 1559}
1603 1560
1561/*
1562 * Free disk inode. Carefully avoids touching the incore inode, all
1563 * manipulations incore are the caller's responsibility.
1564 * The on-disk inode is not changed by this operation, only the
1565 * btree (free inode mask) is changed.
1566 */
1567int
1568xfs_difree(
1569 struct xfs_trans *tp, /* transaction pointer */
1570 xfs_ino_t inode, /* inode to be freed */
1571 struct xfs_bmap_free *flist, /* extents to free */
1572 int *delete,/* set if inode cluster was deleted */
1573 xfs_ino_t *first_ino)/* first inode in deleted cluster */
1574{
1575 /* REFERENCED */
1576 xfs_agblock_t agbno; /* block number containing inode */
1577 struct xfs_buf *agbp; /* buffer for allocation group header */
1578 xfs_agino_t agino; /* allocation group inode number */
1579 xfs_agnumber_t agno; /* allocation group number */
1580 int error; /* error return value */
1581 struct xfs_mount *mp; /* mount structure for filesystem */
1582 struct xfs_inobt_rec_incore rec;/* btree record */
1583
1584 mp = tp->t_mountp;
1585
1586 /*
1587 * Break up inode number into its components.
1588 */
1589 agno = XFS_INO_TO_AGNO(mp, inode);
1590 if (agno >= mp->m_sb.sb_agcount) {
1591 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
1592 __func__, agno, mp->m_sb.sb_agcount);
1593 ASSERT(0);
1594 return XFS_ERROR(EINVAL);
1595 }
1596 agino = XFS_INO_TO_AGINO(mp, inode);
1597 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1598 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
1599 __func__, (unsigned long long)inode,
1600 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
1601 ASSERT(0);
1602 return XFS_ERROR(EINVAL);
1603 }
1604 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1605 if (agbno >= mp->m_sb.sb_agblocks) {
1606 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
1607 __func__, agbno, mp->m_sb.sb_agblocks);
1608 ASSERT(0);
1609 return XFS_ERROR(EINVAL);
1610 }
1611 /*
1612 * Get the allocation group header.
1613 */
1614 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1615 if (error) {
1616 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
1617 __func__, error);
1618 return error;
1619 }
1620
1621 /*
1622 * Fix up the inode allocation btree.
1623 */
1624 error = xfs_difree_inobt(mp, tp, agbp, agino, flist, delete, first_ino,
1625 &rec);
1626 if (error)
1627 goto error0;
1628
1629 return 0;
1630
1631error0:
1632 return error;
1633}
1634
1604STATIC int 1635STATIC int
1605xfs_imap_lookup( 1636xfs_imap_lookup(
1606 struct xfs_mount *mp, 1637 struct xfs_mount *mp,