aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_alloc_btree.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 01:56:32 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:56:32 -0400
commit278d0ca14e889c3932a05d1a68675252a12b3466 (patch)
treea228d171d4aded60b27639e30eca1bf58ed7daa6 /fs/xfs/xfs_alloc_btree.c
parent38bb74237d2d94c1aced2ec626d7d0f317e360da (diff)
[XFS] implement generic xfs_btree_update
From: Dave Chinner <dgc@sgi.com> The most complicated part here is the lastrec tracking for the alloc btree. Most logic is in the update_lastrec method which has to do some hopefully good enough dirty magic to maintain it. [hch: split out from bigger patch and a rework of the lastrec logic] SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32194a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Bill O'Donnell <billodo@sgi.com> Signed-off-by: David Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_alloc_btree.c')
-rw-r--r--fs/xfs/xfs_alloc_btree.c106
1 files changed, 38 insertions, 68 deletions
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 28c6a698f562..c5c32999b810 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -1661,83 +1661,50 @@ xfs_alloc_insert(
1661 return 0; 1661 return 0;
1662} 1662}
1663 1663
1664STATIC struct xfs_btree_cur *
1665xfs_allocbt_dup_cursor(
1666 struct xfs_btree_cur *cur)
1667{
1668 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
1669 cur->bc_private.a.agbp, cur->bc_private.a.agno,
1670 cur->bc_btnum);
1671}
1672
1664/* 1673/*
1665 * Update the record referred to by cur, to the value given by [bno, len]. 1674 * Update the longest extent in the AGF
1666 * This either works (return 0) or gets an EFSCORRUPTED error.
1667 */ 1675 */
1668int /* error */ 1676STATIC void
1669xfs_alloc_update( 1677xfs_allocbt_update_lastrec(
1670 xfs_btree_cur_t *cur, /* btree cursor */ 1678 struct xfs_btree_cur *cur,
1671 xfs_agblock_t bno, /* starting block of extent */ 1679 struct xfs_btree_block *block,
1672 xfs_extlen_t len) /* length of extent */ 1680 union xfs_btree_rec *rec,
1681 int ptr,
1682 int reason)
1673{ 1683{
1674 xfs_alloc_block_t *block; /* btree block to update */ 1684 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1675 int error; /* error return value */ 1685 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
1676 int ptr; /* current record number (updating) */ 1686 __be32 len;
1677 1687
1678 ASSERT(len > 0); 1688 ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
1679 /*
1680 * Pick up the a.g. freelist struct and the current block.
1681 */
1682 block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[0]);
1683#ifdef DEBUG
1684 if ((error = xfs_btree_check_sblock(cur, block, 0, cur->bc_bufs[0])))
1685 return error;
1686#endif
1687 /*
1688 * Get the address of the rec to be updated.
1689 */
1690 ptr = cur->bc_ptrs[0];
1691 {
1692 xfs_alloc_rec_t *rp; /* pointer to updated record */
1693 1689
1694 rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); 1690 switch (reason) {
1691 case LASTREC_UPDATE:
1695 /* 1692 /*
1696 * Fill in the new contents and log them. 1693 * If this is the last leaf block and it's the last record,
1694 * then update the size of the longest extent in the AG.
1697 */ 1695 */
1698 rp->ar_startblock = cpu_to_be32(bno); 1696 if (ptr != xfs_btree_get_numrecs(block))
1699 rp->ar_blockcount = cpu_to_be32(len); 1697 return;
1700 xfs_alloc_log_recs(cur, cur->bc_bufs[0], ptr, ptr); 1698 len = rec->alloc.ar_blockcount;
1701 } 1699 break;
1702 /* 1700 default:
1703 * If it's the by-size btree and it's the last leaf block and 1701 ASSERT(0);
1704 * it's the last record... then update the size of the longest 1702 return;
1705 * extent in the a.g., which we cache in the a.g. freelist header.
1706 */
1707 if (cur->bc_btnum == XFS_BTNUM_CNT &&
1708 be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
1709 ptr == be16_to_cpu(block->bb_numrecs)) {
1710 xfs_agf_t *agf; /* a.g. freespace header */
1711 xfs_agnumber_t seqno;
1712
1713 agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
1714 seqno = be32_to_cpu(agf->agf_seqno);
1715 cur->bc_mp->m_perag[seqno].pagf_longest = len;
1716 agf->agf_longest = cpu_to_be32(len);
1717 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp,
1718 XFS_AGF_LONGEST);
1719 }
1720 /*
1721 * Updating first record in leaf. Pass new key value up to our parent.
1722 */
1723 if (ptr == 1) {
1724 xfs_alloc_key_t key; /* key containing [bno, len] */
1725
1726 key.ar_startblock = cpu_to_be32(bno);
1727 key.ar_blockcount = cpu_to_be32(len);
1728 if ((error = xfs_btree_updkey(cur, (union xfs_btree_key *)&key, 1)))
1729 return error;
1730 } 1703 }
1731 return 0;
1732}
1733 1704
1734STATIC struct xfs_btree_cur * 1705 agf->agf_longest = len;
1735xfs_allocbt_dup_cursor( 1706 cur->bc_mp->m_perag[seqno].pagf_longest = be32_to_cpu(len);
1736 struct xfs_btree_cur *cur) 1707 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST);
1737{
1738 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
1739 cur->bc_private.a.agbp, cur->bc_private.a.agno,
1740 cur->bc_btnum);
1741} 1708}
1742 1709
1743STATIC int 1710STATIC int
@@ -1864,6 +1831,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {
1864 .key_len = sizeof(xfs_alloc_key_t), 1831 .key_len = sizeof(xfs_alloc_key_t),
1865 1832
1866 .dup_cursor = xfs_allocbt_dup_cursor, 1833 .dup_cursor = xfs_allocbt_dup_cursor,
1834 .update_lastrec = xfs_allocbt_update_lastrec,
1867 .get_maxrecs = xfs_allocbt_get_maxrecs, 1835 .get_maxrecs = xfs_allocbt_get_maxrecs,
1868 .init_key_from_rec = xfs_allocbt_init_key_from_rec, 1836 .init_key_from_rec = xfs_allocbt_init_key_from_rec,
1869 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 1837 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
@@ -1902,6 +1870,8 @@ xfs_allocbt_init_cursor(
1902 cur->bc_blocklog = mp->m_sb.sb_blocklog; 1870 cur->bc_blocklog = mp->m_sb.sb_blocklog;
1903 1871
1904 cur->bc_ops = &xfs_allocbt_ops; 1872 cur->bc_ops = &xfs_allocbt_ops;
1873 if (btnum == XFS_BTNUM_CNT)
1874 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
1905 1875
1906 cur->bc_private.a.agbp = agbp; 1876 cur->bc_private.a.agbp = agbp;
1907 cur->bc_private.a.agno = agno; 1877 cur->bc_private.a.agno = agno;