diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 01:55:45 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 01:55:45 -0400 |
commit | 637aa50f461b8ea6b1e8bf9877b0d13d00085043 (patch) | |
tree | a7c00b821dca04fe90614461749b74eff40bd8ed /fs/xfs/xfs_bmap_btree.c | |
parent | 65f1eaeac0efc968797f3ac955b85ba3f5d4f9c8 (diff) |
[XFS] implement generic xfs_btree_increment
From: Dave Chinner <dgc@sgi.com>
Because this is the first major generic btree routine this patch includes
some infrastrucure, first a few routines to deal with a btree block that
can be either in short or long form, second xfs_btree_read_buf_block,
which is the new central routine to read a btree block given a cursor, and
third the new xfs_btree_ptr_addr routine to calculate the address for a
given btree pointer record.
[hch: split out from bigger patch and minor adaptions]
SGI-PV: 985583
SGI-Modid: xfs-linux-melb:xfs-kern:32190a
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_bmap_btree.c')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 88 |
1 files changed, 4 insertions, 84 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index a71010abf6ec..2d29a4980cf7 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -254,7 +254,7 @@ xfs_bmbt_delrec( | |||
254 | if (rbno != NULLFSBLOCK) { | 254 | if (rbno != NULLFSBLOCK) { |
255 | i = xfs_btree_lastrec(tcur, level); | 255 | i = xfs_btree_lastrec(tcur, level); |
256 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 256 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
257 | if ((error = xfs_bmbt_increment(tcur, level, &i))) { | 257 | if ((error = xfs_btree_increment(tcur, level, &i))) { |
258 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 258 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
259 | goto error0; | 259 | goto error0; |
260 | } | 260 | } |
@@ -445,7 +445,7 @@ xfs_bmbt_delrec( | |||
445 | cur->bc_bufs[level] = lbp; | 445 | cur->bc_bufs[level] = lbp; |
446 | cur->bc_ptrs[level] += lrecs; | 446 | cur->bc_ptrs[level] += lrecs; |
447 | cur->bc_ra[level] = 0; | 447 | cur->bc_ra[level] = 0; |
448 | } else if ((error = xfs_bmbt_increment(cur, level + 1, &i))) { | 448 | } else if ((error = xfs_btree_increment(cur, level + 1, &i))) { |
449 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 449 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
450 | goto error0; | 450 | goto error0; |
451 | } | 451 | } |
@@ -929,7 +929,7 @@ xfs_bmbt_lookup( | |||
929 | if (dir == XFS_LOOKUP_GE && keyno > be16_to_cpu(block->bb_numrecs) && | 929 | if (dir == XFS_LOOKUP_GE && keyno > be16_to_cpu(block->bb_numrecs) && |
930 | be64_to_cpu(block->bb_rightsib) != NULLDFSBNO) { | 930 | be64_to_cpu(block->bb_rightsib) != NULLDFSBNO) { |
931 | cur->bc_ptrs[0] = keyno; | 931 | cur->bc_ptrs[0] = keyno; |
932 | if ((error = xfs_bmbt_increment(cur, 0, &i))) { | 932 | if ((error = xfs_btree_increment(cur, 0, &i))) { |
933 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 933 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
934 | return error; | 934 | return error; |
935 | } | 935 | } |
@@ -1202,7 +1202,7 @@ xfs_bmbt_rshift( | |||
1202 | } | 1202 | } |
1203 | i = xfs_btree_lastrec(tcur, level); | 1203 | i = xfs_btree_lastrec(tcur, level); |
1204 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1204 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1205 | if ((error = xfs_bmbt_increment(tcur, level, &i))) { | 1205 | if ((error = xfs_btree_increment(tcur, level, &i))) { |
1206 | XFS_BMBT_TRACE_CURSOR(tcur, ERROR); | 1206 | XFS_BMBT_TRACE_CURSOR(tcur, ERROR); |
1207 | goto error1; | 1207 | goto error1; |
1208 | } | 1208 | } |
@@ -1761,86 +1761,6 @@ xfs_bmbt_disk_get_startoff( | |||
1761 | } | 1761 | } |
1762 | 1762 | ||
1763 | /* | 1763 | /* |
1764 | * Increment cursor by one record at the level. | ||
1765 | * For nonzero levels the leaf-ward information is untouched. | ||
1766 | */ | ||
1767 | int /* error */ | ||
1768 | xfs_bmbt_increment( | ||
1769 | xfs_btree_cur_t *cur, | ||
1770 | int level, | ||
1771 | int *stat) /* success/failure */ | ||
1772 | { | ||
1773 | xfs_bmbt_block_t *block; | ||
1774 | xfs_buf_t *bp; | ||
1775 | int error; /* error return value */ | ||
1776 | xfs_fsblock_t fsbno; | ||
1777 | int lev; | ||
1778 | xfs_mount_t *mp; | ||
1779 | xfs_trans_t *tp; | ||
1780 | |||
1781 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | ||
1782 | XFS_BMBT_TRACE_ARGI(cur, level); | ||
1783 | ASSERT(level < cur->bc_nlevels); | ||
1784 | |||
1785 | xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); | ||
1786 | block = xfs_bmbt_get_block(cur, level, &bp); | ||
1787 | #ifdef DEBUG | ||
1788 | if ((error = xfs_btree_check_lblock(cur, block, level, bp))) { | ||
1789 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1790 | return error; | ||
1791 | } | ||
1792 | #endif | ||
1793 | if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) { | ||
1794 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1795 | *stat = 1; | ||
1796 | return 0; | ||
1797 | } | ||
1798 | if (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO) { | ||
1799 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1800 | *stat = 0; | ||
1801 | return 0; | ||
1802 | } | ||
1803 | for (lev = level + 1; lev < cur->bc_nlevels; lev++) { | ||
1804 | block = xfs_bmbt_get_block(cur, lev, &bp); | ||
1805 | #ifdef DEBUG | ||
1806 | if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) { | ||
1807 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1808 | return error; | ||
1809 | } | ||
1810 | #endif | ||
1811 | if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs)) | ||
1812 | break; | ||
1813 | xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA); | ||
1814 | } | ||
1815 | if (lev == cur->bc_nlevels) { | ||
1816 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1817 | *stat = 0; | ||
1818 | return 0; | ||
1819 | } | ||
1820 | tp = cur->bc_tp; | ||
1821 | mp = cur->bc_mp; | ||
1822 | for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { | ||
1823 | fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); | ||
1824 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, | ||
1825 | XFS_BMAP_BTREE_REF))) { | ||
1826 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1827 | return error; | ||
1828 | } | ||
1829 | lev--; | ||
1830 | xfs_btree_setbuf(cur, lev, bp); | ||
1831 | block = XFS_BUF_TO_BMBT_BLOCK(bp); | ||
1832 | if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) { | ||
1833 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
1834 | return error; | ||
1835 | } | ||
1836 | cur->bc_ptrs[lev] = 1; | ||
1837 | } | ||
1838 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
1839 | *stat = 1; | ||
1840 | return 0; | ||
1841 | } | ||
1842 | |||
1843 | /* | ||
1844 | * Insert the current record at the point referenced by cur. | 1764 | * Insert the current record at the point referenced by cur. |
1845 | * | 1765 | * |
1846 | * A multi-level split of the tree on insert will invalidate the original | 1766 | * A multi-level split of the tree on insert will invalidate the original |