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_alloc_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_alloc_btree.c')
-rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 99 |
1 files changed, 4 insertions, 95 deletions
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 9e2421c31a36..febc2d5ea295 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -303,7 +303,7 @@ xfs_alloc_delrec( | |||
303 | */ | 303 | */ |
304 | i = xfs_btree_lastrec(tcur, level); | 304 | i = xfs_btree_lastrec(tcur, level); |
305 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 305 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
306 | if ((error = xfs_alloc_increment(tcur, level, &i))) | 306 | if ((error = xfs_btree_increment(tcur, level, &i))) |
307 | goto error0; | 307 | goto error0; |
308 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 308 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
309 | i = xfs_btree_lastrec(tcur, level); | 309 | i = xfs_btree_lastrec(tcur, level); |
@@ -517,7 +517,7 @@ xfs_alloc_delrec( | |||
517 | * us, increment the cursor at that level. | 517 | * us, increment the cursor at that level. |
518 | */ | 518 | */ |
519 | else if (level + 1 < cur->bc_nlevels && | 519 | else if (level + 1 < cur->bc_nlevels && |
520 | (error = xfs_alloc_increment(cur, level + 1, &i))) | 520 | (error = xfs_btree_increment(cur, level + 1, &i))) |
521 | return error; | 521 | return error; |
522 | /* | 522 | /* |
523 | * Fix up the number of records in the surviving block. | 523 | * Fix up the number of records in the surviving block. |
@@ -1134,7 +1134,7 @@ xfs_alloc_lookup( | |||
1134 | int i; | 1134 | int i; |
1135 | 1135 | ||
1136 | cur->bc_ptrs[0] = keyno; | 1136 | cur->bc_ptrs[0] = keyno; |
1137 | if ((error = xfs_alloc_increment(cur, 0, &i))) | 1137 | if ((error = xfs_btree_increment(cur, 0, &i))) |
1138 | return error; | 1138 | return error; |
1139 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1139 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
1140 | *stat = 1; | 1140 | *stat = 1; |
@@ -1570,7 +1570,7 @@ xfs_alloc_rshift( | |||
1570 | return error; | 1570 | return error; |
1571 | i = xfs_btree_lastrec(tcur, level); | 1571 | i = xfs_btree_lastrec(tcur, level); |
1572 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1572 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1573 | if ((error = xfs_alloc_increment(tcur, level, &i)) || | 1573 | if ((error = xfs_btree_increment(tcur, level, &i)) || |
1574 | (error = xfs_alloc_updkey(tcur, rkp, level + 1))) | 1574 | (error = xfs_alloc_updkey(tcur, rkp, level + 1))) |
1575 | goto error0; | 1575 | goto error0; |
1576 | xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); | 1576 | xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); |
@@ -1943,97 +1943,6 @@ xfs_alloc_get_rec( | |||
1943 | } | 1943 | } |
1944 | 1944 | ||
1945 | /* | 1945 | /* |
1946 | * Increment cursor by one record at the level. | ||
1947 | * For nonzero levels the leaf-ward information is untouched. | ||
1948 | */ | ||
1949 | int /* error */ | ||
1950 | xfs_alloc_increment( | ||
1951 | xfs_btree_cur_t *cur, /* btree cursor */ | ||
1952 | int level, /* level in btree, 0 is leaf */ | ||
1953 | int *stat) /* success/failure */ | ||
1954 | { | ||
1955 | xfs_alloc_block_t *block; /* btree block */ | ||
1956 | xfs_buf_t *bp; /* tree block buffer */ | ||
1957 | int error; /* error return value */ | ||
1958 | int lev; /* btree level */ | ||
1959 | |||
1960 | ASSERT(level < cur->bc_nlevels); | ||
1961 | /* | ||
1962 | * Read-ahead to the right at this level. | ||
1963 | */ | ||
1964 | xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); | ||
1965 | /* | ||
1966 | * Get a pointer to the btree block. | ||
1967 | */ | ||
1968 | bp = cur->bc_bufs[level]; | ||
1969 | block = XFS_BUF_TO_ALLOC_BLOCK(bp); | ||
1970 | #ifdef DEBUG | ||
1971 | if ((error = xfs_btree_check_sblock(cur, block, level, bp))) | ||
1972 | return error; | ||
1973 | #endif | ||
1974 | /* | ||
1975 | * Increment the ptr at this level. If we're still in the block | ||
1976 | * then we're done. | ||
1977 | */ | ||
1978 | if (++cur->bc_ptrs[level] <= be16_to_cpu(block->bb_numrecs)) { | ||
1979 | *stat = 1; | ||
1980 | return 0; | ||
1981 | } | ||
1982 | /* | ||
1983 | * If we just went off the right edge of the tree, return failure. | ||
1984 | */ | ||
1985 | if (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK) { | ||
1986 | *stat = 0; | ||
1987 | return 0; | ||
1988 | } | ||
1989 | /* | ||
1990 | * March up the tree incrementing pointers. | ||
1991 | * Stop when we don't go off the right edge of a block. | ||
1992 | */ | ||
1993 | for (lev = level + 1; lev < cur->bc_nlevels; lev++) { | ||
1994 | bp = cur->bc_bufs[lev]; | ||
1995 | block = XFS_BUF_TO_ALLOC_BLOCK(bp); | ||
1996 | #ifdef DEBUG | ||
1997 | if ((error = xfs_btree_check_sblock(cur, block, lev, bp))) | ||
1998 | return error; | ||
1999 | #endif | ||
2000 | if (++cur->bc_ptrs[lev] <= be16_to_cpu(block->bb_numrecs)) | ||
2001 | break; | ||
2002 | /* | ||
2003 | * Read-ahead the right block, we're going to read it | ||
2004 | * in the next loop. | ||
2005 | */ | ||
2006 | xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA); | ||
2007 | } | ||
2008 | /* | ||
2009 | * If we went off the root then we are seriously confused. | ||
2010 | */ | ||
2011 | ASSERT(lev < cur->bc_nlevels); | ||
2012 | /* | ||
2013 | * Now walk back down the tree, fixing up the cursor's buffer | ||
2014 | * pointers and key numbers. | ||
2015 | */ | ||
2016 | for (bp = cur->bc_bufs[lev], block = XFS_BUF_TO_ALLOC_BLOCK(bp); | ||
2017 | lev > level; ) { | ||
2018 | xfs_agblock_t agbno; /* block number of btree block */ | ||
2019 | |||
2020 | agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur)); | ||
2021 | if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp, | ||
2022 | cur->bc_private.a.agno, agbno, 0, &bp, | ||
2023 | XFS_ALLOC_BTREE_REF))) | ||
2024 | return error; | ||
2025 | lev--; | ||
2026 | xfs_btree_setbuf(cur, lev, bp); | ||
2027 | block = XFS_BUF_TO_ALLOC_BLOCK(bp); | ||
2028 | if ((error = xfs_btree_check_sblock(cur, block, lev, bp))) | ||
2029 | return error; | ||
2030 | cur->bc_ptrs[lev] = 1; | ||
2031 | } | ||
2032 | *stat = 1; | ||
2033 | return 0; | ||
2034 | } | ||
2035 | |||
2036 | /* | ||
2037 | * Insert the current record at the point referenced by cur. | 1946 | * Insert the current record at the point referenced by cur. |
2038 | * The cursor may be inconsistent on return if splits have been done. | 1947 | * The cursor may be inconsistent on return if splits have been done. |
2039 | */ | 1948 | */ |