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_ialloc_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_ialloc_btree.c')
-rw-r--r-- | fs/xfs/xfs_ialloc_btree.c | 99 |
1 files changed, 4 insertions, 95 deletions
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index fc6db94492dc..41717da63696 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -253,7 +253,7 @@ xfs_inobt_delrec( | |||
253 | */ | 253 | */ |
254 | i = xfs_btree_lastrec(tcur, level); | 254 | i = xfs_btree_lastrec(tcur, level); |
255 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 255 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
256 | if ((error = xfs_inobt_increment(tcur, level, &i))) | 256 | if ((error = xfs_btree_increment(tcur, level, &i))) |
257 | goto error0; | 257 | goto error0; |
258 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 258 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
259 | i = xfs_btree_lastrec(tcur, level); | 259 | i = xfs_btree_lastrec(tcur, level); |
@@ -463,7 +463,7 @@ xfs_inobt_delrec( | |||
463 | * us, increment the cursor at that level. | 463 | * us, increment the cursor at that level. |
464 | */ | 464 | */ |
465 | else if (level + 1 < cur->bc_nlevels && | 465 | else if (level + 1 < cur->bc_nlevels && |
466 | (error = xfs_alloc_increment(cur, level + 1, &i))) | 466 | (error = xfs_btree_increment(cur, level + 1, &i))) |
467 | return error; | 467 | return error; |
468 | /* | 468 | /* |
469 | * Fix up the number of records in the surviving block. | 469 | * Fix up the number of records in the surviving block. |
@@ -1014,7 +1014,7 @@ xfs_inobt_lookup( | |||
1014 | int i; | 1014 | int i; |
1015 | 1015 | ||
1016 | cur->bc_ptrs[0] = keyno; | 1016 | cur->bc_ptrs[0] = keyno; |
1017 | if ((error = xfs_inobt_increment(cur, 0, &i))) | 1017 | if ((error = xfs_btree_increment(cur, 0, &i))) |
1018 | return error; | 1018 | return error; |
1019 | ASSERT(i == 1); | 1019 | ASSERT(i == 1); |
1020 | *stat = 1; | 1020 | *stat = 1; |
@@ -1443,7 +1443,7 @@ xfs_inobt_rshift( | |||
1443 | if ((error = xfs_btree_dup_cursor(cur, &tcur))) | 1443 | if ((error = xfs_btree_dup_cursor(cur, &tcur))) |
1444 | return error; | 1444 | return error; |
1445 | xfs_btree_lastrec(tcur, level); | 1445 | xfs_btree_lastrec(tcur, level); |
1446 | if ((error = xfs_inobt_increment(tcur, level, &i)) || | 1446 | if ((error = xfs_btree_increment(tcur, level, &i)) || |
1447 | (error = xfs_inobt_updkey(tcur, rkp, level + 1))) { | 1447 | (error = xfs_inobt_updkey(tcur, rkp, level + 1))) { |
1448 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); | 1448 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); |
1449 | return error; | 1449 | return error; |
@@ -1821,97 +1821,6 @@ xfs_inobt_get_rec( | |||
1821 | } | 1821 | } |
1822 | 1822 | ||
1823 | /* | 1823 | /* |
1824 | * Increment cursor by one record at the level. | ||
1825 | * For nonzero levels the leaf-ward information is untouched. | ||
1826 | */ | ||
1827 | int /* error */ | ||
1828 | xfs_inobt_increment( | ||
1829 | xfs_btree_cur_t *cur, /* btree cursor */ | ||
1830 | int level, /* level in btree, 0 is leaf */ | ||
1831 | int *stat) /* success/failure */ | ||
1832 | { | ||
1833 | xfs_inobt_block_t *block; /* btree block */ | ||
1834 | xfs_buf_t *bp; /* buffer containing btree block */ | ||
1835 | int error; /* error return value */ | ||
1836 | int lev; /* btree level */ | ||
1837 | |||
1838 | ASSERT(level < cur->bc_nlevels); | ||
1839 | /* | ||
1840 | * Read-ahead to the right at this level. | ||
1841 | */ | ||
1842 | xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); | ||
1843 | /* | ||
1844 | * Get a pointer to the btree block. | ||
1845 | */ | ||
1846 | bp = cur->bc_bufs[level]; | ||
1847 | block = XFS_BUF_TO_INOBT_BLOCK(bp); | ||
1848 | #ifdef DEBUG | ||
1849 | if ((error = xfs_btree_check_sblock(cur, block, level, bp))) | ||
1850 | return error; | ||
1851 | #endif | ||
1852 | /* | ||
1853 | * Increment the ptr at this level. If we're still in the block | ||
1854 | * then we're done. | ||
1855 | */ | ||
1856 | if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) { | ||
1857 | *stat = 1; | ||
1858 | return 0; | ||
1859 | } | ||
1860 | /* | ||
1861 | * If we just went off the right edge of the tree, return failure. | ||
1862 | */ | ||
1863 | if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) { | ||
1864 | *stat = 0; | ||
1865 | return 0; | ||
1866 | } | ||
1867 | /* | ||
1868 | * March up the tree incrementing pointers. | ||
1869 | * Stop when we don't go off the right edge of a block. | ||
1870 | */ | ||
1871 | for (lev = level + 1; lev < cur->bc_nlevels; lev++) { | ||
1872 | bp = cur->bc_bufs[lev]; | ||
1873 | block = XFS_BUF_TO_INOBT_BLOCK(bp); | ||
1874 | #ifdef DEBUG | ||
1875 | if ((error = xfs_btree_check_sblock(cur, block, lev, bp))) | ||
1876 | return error; | ||
1877 | #endif | ||
1878 | if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs)) | ||
1879 | break; | ||
1880 | /* | ||
1881 | * Read-ahead the right block, we're going to read it | ||
1882 | * in the next loop. | ||
1883 | */ | ||
1884 | xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA); | ||
1885 | } | ||
1886 | /* | ||
1887 | * If we went off the root then we are seriously confused. | ||
1888 | */ | ||
1889 | ASSERT(lev < cur->bc_nlevels); | ||
1890 | /* | ||
1891 | * Now walk back down the tree, fixing up the cursor's buffer | ||
1892 | * pointers and key numbers. | ||
1893 | */ | ||
1894 | for (bp = cur->bc_bufs[lev], block = XFS_BUF_TO_INOBT_BLOCK(bp); | ||
1895 | lev > level; ) { | ||
1896 | xfs_agblock_t agbno; /* block number of btree block */ | ||
1897 | |||
1898 | agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); | ||
1899 | if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, | ||
1900 | cur->bc_private.a.agno, agbno, 0, &bp, | ||
1901 | XFS_INO_BTREE_REF))) | ||
1902 | return error; | ||
1903 | lev--; | ||
1904 | xfs_btree_setbuf(cur, lev, bp); | ||
1905 | block = XFS_BUF_TO_INOBT_BLOCK(bp); | ||
1906 | if ((error = xfs_btree_check_sblock(cur, block, lev, bp))) | ||
1907 | return error; | ||
1908 | cur->bc_ptrs[lev] = 1; | ||
1909 | } | ||
1910 | *stat = 1; | ||
1911 | return 0; | ||
1912 | } | ||
1913 | |||
1914 | /* | ||
1915 | * Insert the current record at the point referenced by cur. | 1824 | * Insert the current record at the point referenced by cur. |
1916 | * The cursor may be inconsistent on return if splits have been done. | 1825 | * The cursor may be inconsistent on return if splits have been done. |
1917 | */ | 1826 | */ |