aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 01:55:58 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:55:58 -0400
commit8df4da4a0a642d3a016028c0d922bcb4d5a4a6d7 (patch)
tree29b07230f8269ef12a10665d757a6e935c4e2e49
parent637aa50f461b8ea6b1e8bf9877b0d13d00085043 (diff)
[XFS] implement generic xfs_btree_decrement
From: Dave Chinner <dgc@sgi.com> [hch: split out from bigger patch and minor adaptions] SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32191a 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>
-rw-r--r--fs/xfs/xfs_alloc.c12
-rw-r--r--fs/xfs/xfs_alloc_btree.c98
-rw-r--r--fs/xfs/xfs_alloc_btree.h6
-rw-r--r--fs/xfs/xfs_bmap.c14
-rw-r--r--fs/xfs/xfs_bmap_btree.c90
-rw-r--r--fs/xfs/xfs_bmap_btree.h1
-rw-r--r--fs/xfs/xfs_btree.c99
-rw-r--r--fs/xfs/xfs_btree.h1
-rw-r--r--fs/xfs/xfs_ialloc.c4
-rw-r--r--fs/xfs/xfs_ialloc_btree.c98
-rw-r--r--fs/xfs/xfs_ialloc_btree.h6
11 files changed, 137 insertions, 292 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index b8bb694b7da3..7ca6903e2354 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -961,7 +961,7 @@ xfs_alloc_ag_vextent_near(
961 args->minlen, &ltbnoa, &ltlena); 961 args->minlen, &ltbnoa, &ltlena);
962 if (ltlena >= args->minlen) 962 if (ltlena >= args->minlen)
963 break; 963 break;
964 if ((error = xfs_alloc_decrement(bno_cur_lt, 0, &i))) 964 if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i)))
965 goto error0; 965 goto error0;
966 if (!i) { 966 if (!i) {
967 xfs_btree_del_cursor(bno_cur_lt, 967 xfs_btree_del_cursor(bno_cur_lt,
@@ -1162,7 +1162,7 @@ xfs_alloc_ag_vextent_near(
1162 /* 1162 /*
1163 * Fell off the left end. 1163 * Fell off the left end.
1164 */ 1164 */
1165 if ((error = xfs_alloc_decrement( 1165 if ((error = xfs_btree_decrement(
1166 bno_cur_lt, 0, &i))) 1166 bno_cur_lt, 0, &i)))
1167 goto error0; 1167 goto error0;
1168 if (!i) { 1168 if (!i) {
@@ -1321,7 +1321,7 @@ xfs_alloc_ag_vextent_size(
1321 bestflen = flen; 1321 bestflen = flen;
1322 bestfbno = fbno; 1322 bestfbno = fbno;
1323 for (;;) { 1323 for (;;) {
1324 if ((error = xfs_alloc_decrement(cnt_cur, 0, &i))) 1324 if ((error = xfs_btree_decrement(cnt_cur, 0, &i)))
1325 goto error0; 1325 goto error0;
1326 if (i == 0) 1326 if (i == 0)
1327 break; 1327 break;
@@ -1416,7 +1416,7 @@ xfs_alloc_ag_vextent_small(
1416 xfs_extlen_t flen; 1416 xfs_extlen_t flen;
1417 int i; 1417 int i;
1418 1418
1419 if ((error = xfs_alloc_decrement(ccur, 0, &i))) 1419 if ((error = xfs_btree_decrement(ccur, 0, &i)))
1420 goto error0; 1420 goto error0;
1421 if (i) { 1421 if (i) {
1422 if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) 1422 if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i)))
@@ -1607,7 +1607,7 @@ xfs_free_ag_extent(
1607 /* 1607 /*
1608 * Move the by-block cursor back to the left neighbor. 1608 * Move the by-block cursor back to the left neighbor.
1609 */ 1609 */
1610 if ((error = xfs_alloc_decrement(bno_cur, 0, &i))) 1610 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
1611 goto error0; 1611 goto error0;
1612 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1612 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1613#ifdef DEBUG 1613#ifdef DEBUG
@@ -1653,7 +1653,7 @@ xfs_free_ag_extent(
1653 * Back up the by-block cursor to the left neighbor, and 1653 * Back up the by-block cursor to the left neighbor, and
1654 * update its length. 1654 * update its length.
1655 */ 1655 */
1656 if ((error = xfs_alloc_decrement(bno_cur, 0, &i))) 1656 if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
1657 goto error0; 1657 goto error0;
1658 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1658 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1659 nbno = ltbno; 1659 nbno = ltbno;
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index febc2d5ea295..6b45481ad5b0 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -256,7 +256,7 @@ xfs_alloc_delrec(
256 xfs_btree_setbuf(cur, level, NULL); 256 xfs_btree_setbuf(cur, level, NULL);
257 cur->bc_nlevels--; 257 cur->bc_nlevels--;
258 } else if (level > 0 && 258 } else if (level > 0 &&
259 (error = xfs_alloc_decrement(cur, level, &i))) 259 (error = xfs_btree_decrement(cur, level, &i)))
260 return error; 260 return error;
261 *stat = 1; 261 *stat = 1;
262 return 0; 262 return 0;
@@ -272,7 +272,7 @@ xfs_alloc_delrec(
272 * the minimum, we're done. 272 * the minimum, we're done.
273 */ 273 */
274 if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { 274 if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
275 if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) 275 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
276 return error; 276 return error;
277 *stat = 1; 277 *stat = 1;
278 return 0; 278 return 0;
@@ -336,7 +336,7 @@ xfs_alloc_delrec(
336 xfs_btree_del_cursor(tcur, 336 xfs_btree_del_cursor(tcur,
337 XFS_BTREE_NOERROR); 337 XFS_BTREE_NOERROR);
338 if (level > 0 && 338 if (level > 0 &&
339 (error = xfs_alloc_decrement(cur, level, 339 (error = xfs_btree_decrement(cur, level,
340 &i))) 340 &i)))
341 return error; 341 return error;
342 *stat = 1; 342 *stat = 1;
@@ -352,7 +352,7 @@ xfs_alloc_delrec(
352 if (lbno != NULLAGBLOCK) { 352 if (lbno != NULLAGBLOCK) {
353 i = xfs_btree_firstrec(tcur, level); 353 i = xfs_btree_firstrec(tcur, level);
354 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 354 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
355 if ((error = xfs_alloc_decrement(tcur, level, &i))) 355 if ((error = xfs_btree_decrement(tcur, level, &i)))
356 goto error0; 356 goto error0;
357 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 357 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
358 } 358 }
@@ -368,7 +368,7 @@ xfs_alloc_delrec(
368 */ 368 */
369 i = xfs_btree_firstrec(tcur, level); 369 i = xfs_btree_firstrec(tcur, level);
370 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 370 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
371 if ((error = xfs_alloc_decrement(tcur, level, &i))) 371 if ((error = xfs_btree_decrement(tcur, level, &i)))
372 goto error0; 372 goto error0;
373 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 373 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
374 xfs_btree_firstrec(tcur, level); 374 xfs_btree_firstrec(tcur, level);
@@ -468,7 +468,7 @@ xfs_alloc_delrec(
468 * Just return. This is probably a logic error, but it's not fatal. 468 * Just return. This is probably a logic error, but it's not fatal.
469 */ 469 */
470 else { 470 else {
471 if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) 471 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
472 return error; 472 return error;
473 *stat = 1; 473 *stat = 1;
474 return 0; 474 return 0;
@@ -1780,90 +1780,6 @@ xfs_alloc_updkey(
1780 */ 1780 */
1781 1781
1782/* 1782/*
1783 * Decrement cursor by one record at the level.
1784 * For nonzero levels the leaf-ward information is untouched.
1785 */
1786int /* error */
1787xfs_alloc_decrement(
1788 xfs_btree_cur_t *cur, /* btree cursor */
1789 int level, /* level in btree, 0 is leaf */
1790 int *stat) /* success/failure */
1791{
1792 xfs_alloc_block_t *block; /* btree block */
1793 int error; /* error return value */
1794 int lev; /* btree level */
1795
1796 ASSERT(level < cur->bc_nlevels);
1797 /*
1798 * Read-ahead to the left at this level.
1799 */
1800 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1801 /*
1802 * Decrement the ptr at this level. If we're still in the block
1803 * then we're done.
1804 */
1805 if (--cur->bc_ptrs[level] > 0) {
1806 *stat = 1;
1807 return 0;
1808 }
1809 /*
1810 * Get a pointer to the btree block.
1811 */
1812 block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[level]);
1813#ifdef DEBUG
1814 if ((error = xfs_btree_check_sblock(cur, block, level,
1815 cur->bc_bufs[level])))
1816 return error;
1817#endif
1818 /*
1819 * If we just went off the left edge of the tree, return failure.
1820 */
1821 if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
1822 *stat = 0;
1823 return 0;
1824 }
1825 /*
1826 * March up the tree decrementing pointers.
1827 * Stop when we don't go off the left edge of a block.
1828 */
1829 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1830 if (--cur->bc_ptrs[lev] > 0)
1831 break;
1832 /*
1833 * Read-ahead the left block, we're going to read it
1834 * in the next loop.
1835 */
1836 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1837 }
1838 /*
1839 * If we went off the root then we are seriously confused.
1840 */
1841 ASSERT(lev < cur->bc_nlevels);
1842 /*
1843 * Now walk back down the tree, fixing up the cursor's buffer
1844 * pointers and key numbers.
1845 */
1846 for (block = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]); lev > level; ) {
1847 xfs_agblock_t agbno; /* block number of btree block */
1848 xfs_buf_t *bp; /* buffer pointer for block */
1849
1850 agbno = be32_to_cpu(*XFS_ALLOC_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
1851 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
1852 cur->bc_private.a.agno, agbno, 0, &bp,
1853 XFS_ALLOC_BTREE_REF)))
1854 return error;
1855 lev--;
1856 xfs_btree_setbuf(cur, lev, bp);
1857 block = XFS_BUF_TO_ALLOC_BLOCK(bp);
1858 if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
1859 return error;
1860 cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
1861 }
1862 *stat = 1;
1863 return 0;
1864}
1865
1866/*
1867 * Delete the record pointed to by cur. 1783 * Delete the record pointed to by cur.
1868 * The cursor refers to the place where the record was (could be inserted) 1784 * The cursor refers to the place where the record was (could be inserted)
1869 * when the operation returns. 1785 * when the operation returns.
@@ -1889,7 +1805,7 @@ xfs_alloc_delete(
1889 if (i == 0) { 1805 if (i == 0) {
1890 for (level = 1; level < cur->bc_nlevels; level++) { 1806 for (level = 1; level < cur->bc_nlevels; level++) {
1891 if (cur->bc_ptrs[level] == 0) { 1807 if (cur->bc_ptrs[level] == 0) {
1892 if ((error = xfs_alloc_decrement(cur, level, &i))) 1808 if ((error = xfs_btree_decrement(cur, level, &i)))
1893 return error; 1809 return error;
1894 break; 1810 break;
1895 } 1811 }
diff --git a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h
index 643cfabbf675..b59d7fc78fe6 100644
--- a/fs/xfs/xfs_alloc_btree.h
+++ b/fs/xfs/xfs_alloc_btree.h
@@ -95,12 +95,6 @@ typedef struct xfs_btree_sblock xfs_alloc_block_t;
95 XFS_BTREE_PTR_ADDR(xfs_alloc, bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur)) 95 XFS_BTREE_PTR_ADDR(xfs_alloc, bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
96 96
97/* 97/*
98 * Decrement cursor by one record at the level.
99 * For nonzero levels the leaf-ward information is untouched.
100 */
101extern int xfs_alloc_decrement(struct xfs_btree_cur *cur, int level, int *stat);
102
103/*
104 * Delete the record pointed to by cur. 98 * Delete the record pointed to by cur.
105 * The cursor refers to the place where the record was (could be inserted) 99 * The cursor refers to the place where the record was (could be inserted)
106 * when the operation returns. 100 * when the operation returns.
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 4b1ec44c80aa..bdbab54948fc 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -820,7 +820,7 @@ xfs_bmap_add_extent_delay_real(
820 if ((error = xfs_bmbt_delete(cur, &i))) 820 if ((error = xfs_bmbt_delete(cur, &i)))
821 goto done; 821 goto done;
822 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 822 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
823 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 823 if ((error = xfs_btree_decrement(cur, 0, &i)))
824 goto done; 824 goto done;
825 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 825 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
826 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 826 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
@@ -1381,13 +1381,13 @@ xfs_bmap_add_extent_unwritten_real(
1381 if ((error = xfs_bmbt_delete(cur, &i))) 1381 if ((error = xfs_bmbt_delete(cur, &i)))
1382 goto done; 1382 goto done;
1383 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1383 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1384 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1384 if ((error = xfs_btree_decrement(cur, 0, &i)))
1385 goto done; 1385 goto done;
1386 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1386 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1387 if ((error = xfs_bmbt_delete(cur, &i))) 1387 if ((error = xfs_bmbt_delete(cur, &i)))
1388 goto done; 1388 goto done;
1389 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1389 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1390 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1390 if ((error = xfs_btree_decrement(cur, 0, &i)))
1391 goto done; 1391 goto done;
1392 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1392 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1393 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 1393 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
@@ -1430,7 +1430,7 @@ xfs_bmap_add_extent_unwritten_real(
1430 if ((error = xfs_bmbt_delete(cur, &i))) 1430 if ((error = xfs_bmbt_delete(cur, &i)))
1431 goto done; 1431 goto done;
1432 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1432 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1433 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1433 if ((error = xfs_btree_decrement(cur, 0, &i)))
1434 goto done; 1434 goto done;
1435 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1435 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1436 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, 1436 if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
@@ -1473,7 +1473,7 @@ xfs_bmap_add_extent_unwritten_real(
1473 if ((error = xfs_bmbt_delete(cur, &i))) 1473 if ((error = xfs_bmbt_delete(cur, &i)))
1474 goto done; 1474 goto done;
1475 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1475 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1476 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1476 if ((error = xfs_btree_decrement(cur, 0, &i)))
1477 goto done; 1477 goto done;
1478 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 1478 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
1479 if ((error = xfs_bmbt_update(cur, new->br_startoff, 1479 if ((error = xfs_bmbt_update(cur, new->br_startoff,
@@ -1556,7 +1556,7 @@ xfs_bmap_add_extent_unwritten_real(
1556 PREV.br_blockcount - new->br_blockcount, 1556 PREV.br_blockcount - new->br_blockcount,
1557 oldext))) 1557 oldext)))
1558 goto done; 1558 goto done;
1559 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 1559 if ((error = xfs_btree_decrement(cur, 0, &i)))
1560 goto done; 1560 goto done;
1561 if (xfs_bmbt_update(cur, LEFT.br_startoff, 1561 if (xfs_bmbt_update(cur, LEFT.br_startoff,
1562 LEFT.br_startblock, 1562 LEFT.br_startblock,
@@ -2108,7 +2108,7 @@ xfs_bmap_add_extent_hole_real(
2108 if ((error = xfs_bmbt_delete(cur, &i))) 2108 if ((error = xfs_bmbt_delete(cur, &i)))
2109 goto done; 2109 goto done;
2110 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2110 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2111 if ((error = xfs_bmbt_decrement(cur, 0, &i))) 2111 if ((error = xfs_btree_decrement(cur, 0, &i)))
2112 goto done; 2112 goto done;
2113 XFS_WANT_CORRUPTED_GOTO(i == 1, done); 2113 XFS_WANT_CORRUPTED_GOTO(i == 1, done);
2114 if ((error = xfs_bmbt_update(cur, left.br_startoff, 2114 if ((error = xfs_bmbt_update(cur, left.br_startoff,
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 2d29a4980cf7..7b5181d34a5b 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -203,7 +203,7 @@ xfs_bmbt_delrec(
203 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 203 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
204 goto error0; 204 goto error0;
205 } 205 }
206 if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) { 206 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
207 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 207 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
208 goto error0; 208 goto error0;
209 } 209 }
@@ -216,7 +216,7 @@ xfs_bmbt_delrec(
216 goto error0; 216 goto error0;
217 } 217 }
218 if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) { 218 if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
219 if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &j))) { 219 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
220 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 220 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
221 goto error0; 221 goto error0;
222 } 222 }
@@ -237,7 +237,7 @@ xfs_bmbt_delrec(
237 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 237 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
238 goto error0; 238 goto error0;
239 } 239 }
240 if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) { 240 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
241 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 241 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
242 goto error0; 242 goto error0;
243 } 243 }
@@ -282,7 +282,7 @@ xfs_bmbt_delrec(
282 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); 282 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
283 tcur = NULL; 283 tcur = NULL;
284 if (level > 0) { 284 if (level > 0) {
285 if ((error = xfs_bmbt_decrement(cur, 285 if ((error = xfs_btree_decrement(cur,
286 level, &i))) { 286 level, &i))) {
287 XFS_BMBT_TRACE_CURSOR(cur, 287 XFS_BMBT_TRACE_CURSOR(cur,
288 ERROR); 288 ERROR);
@@ -298,7 +298,7 @@ xfs_bmbt_delrec(
298 if (lbno != NULLFSBLOCK) { 298 if (lbno != NULLFSBLOCK) {
299 i = xfs_btree_firstrec(tcur, level); 299 i = xfs_btree_firstrec(tcur, level);
300 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 300 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
301 if ((error = xfs_bmbt_decrement(tcur, level, &i))) { 301 if ((error = xfs_btree_decrement(tcur, level, &i))) {
302 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 302 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
303 goto error0; 303 goto error0;
304 } 304 }
@@ -311,7 +311,7 @@ xfs_bmbt_delrec(
311 /* 311 /*
312 * decrement to last in block 312 * decrement to last in block
313 */ 313 */
314 if ((error = xfs_bmbt_decrement(tcur, level, &i))) { 314 if ((error = xfs_btree_decrement(tcur, level, &i))) {
315 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 315 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
316 goto error0; 316 goto error0;
317 } 317 }
@@ -383,7 +383,7 @@ xfs_bmbt_delrec(
383 } 383 }
384 lrecs = be16_to_cpu(left->bb_numrecs); 384 lrecs = be16_to_cpu(left->bb_numrecs);
385 } else { 385 } else {
386 if (level > 0 && (error = xfs_bmbt_decrement(cur, level, &i))) { 386 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
387 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 387 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
388 goto error0; 388 goto error0;
389 } 389 }
@@ -1487,80 +1487,6 @@ xfs_bmdr_to_bmbt(
1487} 1487}
1488 1488
1489/* 1489/*
1490 * Decrement cursor by one record at the level.
1491 * For nonzero levels the leaf-ward information is untouched.
1492 */
1493int /* error */
1494xfs_bmbt_decrement(
1495 xfs_btree_cur_t *cur,
1496 int level,
1497 int *stat) /* success/failure */
1498{
1499 xfs_bmbt_block_t *block;
1500 xfs_buf_t *bp;
1501 int error; /* error return value */
1502 xfs_fsblock_t fsbno;
1503 int lev;
1504 xfs_mount_t *mp;
1505 xfs_trans_t *tp;
1506
1507 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
1508 XFS_BMBT_TRACE_ARGI(cur, level);
1509 ASSERT(level < cur->bc_nlevels);
1510
1511 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1512
1513 if (--cur->bc_ptrs[level] > 0) {
1514 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1515 *stat = 1;
1516 return 0;
1517 }
1518 block = xfs_bmbt_get_block(cur, level, &bp);
1519#ifdef DEBUG
1520 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
1521 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1522 return error;
1523 }
1524#endif
1525 if (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO) {
1526 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1527 *stat = 0;
1528 return 0;
1529 }
1530 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1531 if (--cur->bc_ptrs[lev] > 0)
1532 break;
1533 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1534 }
1535 if (lev == cur->bc_nlevels) {
1536 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1537 *stat = 0;
1538 return 0;
1539 }
1540 tp = cur->bc_tp;
1541 mp = cur->bc_mp;
1542 for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
1543 fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
1544 if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
1545 XFS_BMAP_BTREE_REF))) {
1546 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1547 return error;
1548 }
1549 lev--;
1550 xfs_btree_setbuf(cur, lev, bp);
1551 block = XFS_BUF_TO_BMBT_BLOCK(bp);
1552 if ((error = xfs_btree_check_lblock(cur, block, lev, bp))) {
1553 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1554 return error;
1555 }
1556 cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
1557 }
1558 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
1559 *stat = 1;
1560 return 0;
1561}
1562
1563/*
1564 * Delete the record pointed to by cur. 1490 * Delete the record pointed to by cur.
1565 */ 1491 */
1566int /* error */ 1492int /* error */
@@ -1582,7 +1508,7 @@ xfs_bmbt_delete(
1582 if (i == 0) { 1508 if (i == 0) {
1583 for (level = 1; level < cur->bc_nlevels; level++) { 1509 for (level = 1; level < cur->bc_nlevels; level++) {
1584 if (cur->bc_ptrs[level] == 0) { 1510 if (cur->bc_ptrs[level] == 0) {
1585 if ((error = xfs_bmbt_decrement(cur, level, 1511 if ((error = xfs_btree_decrement(cur, level,
1586 &i))) { 1512 &i))) {
1587 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 1513 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
1588 return error; 1514 return error;
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index a45be38d9a37..1e0f1d105059 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -237,7 +237,6 @@ typedef struct xfs_btree_lblock xfs_bmbt_block_t;
237 * Prototypes for xfs_bmap.c to call. 237 * Prototypes for xfs_bmap.c to call.
238 */ 238 */
239extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); 239extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
240extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
241extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *); 240extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
242extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); 241extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
243extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur, 242extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index e9ab86b7990e..3d561f8f78d0 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -1171,3 +1171,102 @@ error0:
1171 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 1171 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1172 return error; 1172 return error;
1173} 1173}
1174
1175/*
1176 * Decrement cursor by one record at the level.
1177 * For nonzero levels the leaf-ward information is untouched.
1178 */
1179int /* error */
1180xfs_btree_decrement(
1181 struct xfs_btree_cur *cur,
1182 int level,
1183 int *stat) /* success/failure */
1184{
1185 struct xfs_btree_block *block;
1186 xfs_buf_t *bp;
1187 int error; /* error return value */
1188 int lev;
1189 union xfs_btree_ptr ptr;
1190
1191 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
1192 XFS_BTREE_TRACE_ARGI(cur, level);
1193
1194 ASSERT(level < cur->bc_nlevels);
1195
1196 /* Read-ahead to the left at this level. */
1197 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1198
1199 /* We're done if we remain in the block after the decrement. */
1200 if (--cur->bc_ptrs[level] > 0)
1201 goto out1;
1202
1203 /* Get a pointer to the btree block. */
1204 block = xfs_btree_get_block(cur, level, &bp);
1205
1206#ifdef DEBUG
1207 error = xfs_btree_check_block(cur, block, level, bp);
1208 if (error)
1209 goto error0;
1210#endif
1211
1212 /* Fail if we just went off the left edge of the tree. */
1213 xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
1214 if (xfs_btree_ptr_is_null(cur, &ptr))
1215 goto out0;
1216
1217 XFS_BTREE_STATS_INC(cur, decrement);
1218
1219 /*
1220 * March up the tree decrementing pointers.
1221 * Stop when we don't go off the left edge of a block.
1222 */
1223 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1224 if (--cur->bc_ptrs[lev] > 0)
1225 break;
1226 /* Read-ahead the left block for the next loop. */
1227 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1228 }
1229
1230 /*
1231 * If we went off the root then we are seriously confused.
1232 * or the root of the tree is in an inode.
1233 */
1234 if (lev == cur->bc_nlevels) {
1235 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
1236 goto out0;
1237 ASSERT(0);
1238 error = EFSCORRUPTED;
1239 goto error0;
1240 }
1241 ASSERT(lev < cur->bc_nlevels);
1242
1243 /*
1244 * Now walk back down the tree, fixing up the cursor's buffer
1245 * pointers and key numbers.
1246 */
1247 for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
1248 union xfs_btree_ptr *ptrp;
1249
1250 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1251 error = xfs_btree_read_buf_block(cur, ptrp, --lev,
1252 0, &block, &bp);
1253 if (error)
1254 goto error0;
1255 xfs_btree_setbuf(cur, lev, bp);
1256 cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block);
1257 }
1258out1:
1259 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1260 *stat = 1;
1261 return 0;
1262
1263out0:
1264 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
1265 *stat = 0;
1266 return 0;
1267
1268error0:
1269 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
1270 return error;
1271}
1272
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index f5a4b8ec4cdd..52b2da6ab32e 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -506,6 +506,7 @@ xfs_btree_setbuf(
506 * Common btree core entry points. 506 * Common btree core entry points.
507 */ 507 */
508int xfs_btree_increment(struct xfs_btree_cur *, int, int *); 508int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
509int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
509 510
510/* 511/*
511 * Helpers. 512 * Helpers.
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 3a8f0670e070..d36b42bf3ff6 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -739,7 +739,7 @@ nextag:
739 /* 739 /*
740 * Search left with tcur, back up 1 record. 740 * Search left with tcur, back up 1 record.
741 */ 741 */
742 if ((error = xfs_inobt_decrement(tcur, 0, &i))) 742 if ((error = xfs_btree_decrement(tcur, 0, &i)))
743 goto error1; 743 goto error1;
744 doneleft = !i; 744 doneleft = !i;
745 if (!doneleft) { 745 if (!doneleft) {
@@ -815,7 +815,7 @@ nextag:
815 * further left. 815 * further left.
816 */ 816 */
817 if (useleft) { 817 if (useleft) {
818 if ((error = xfs_inobt_decrement(tcur, 0, 818 if ((error = xfs_btree_decrement(tcur, 0,
819 &i))) 819 &i)))
820 goto error1; 820 goto error1;
821 doneleft = !i; 821 doneleft = !i;
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 41717da63696..9099a32f9972 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -205,7 +205,7 @@ xfs_inobt_delrec(
205 cur->bc_bufs[level] = NULL; 205 cur->bc_bufs[level] = NULL;
206 cur->bc_nlevels--; 206 cur->bc_nlevels--;
207 } else if (level > 0 && 207 } else if (level > 0 &&
208 (error = xfs_inobt_decrement(cur, level, &i))) 208 (error = xfs_btree_decrement(cur, level, &i)))
209 return error; 209 return error;
210 *stat = 1; 210 *stat = 1;
211 return 0; 211 return 0;
@@ -222,7 +222,7 @@ xfs_inobt_delrec(
222 */ 222 */
223 if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) { 223 if (numrecs >= XFS_INOBT_BLOCK_MINRECS(level, cur)) {
224 if (level > 0 && 224 if (level > 0 &&
225 (error = xfs_inobt_decrement(cur, level, &i))) 225 (error = xfs_btree_decrement(cur, level, &i)))
226 return error; 226 return error;
227 *stat = 1; 227 *stat = 1;
228 return 0; 228 return 0;
@@ -286,7 +286,7 @@ xfs_inobt_delrec(
286 xfs_btree_del_cursor(tcur, 286 xfs_btree_del_cursor(tcur,
287 XFS_BTREE_NOERROR); 287 XFS_BTREE_NOERROR);
288 if (level > 0 && 288 if (level > 0 &&
289 (error = xfs_inobt_decrement(cur, level, 289 (error = xfs_btree_decrement(cur, level,
290 &i))) 290 &i)))
291 return error; 291 return error;
292 *stat = 1; 292 *stat = 1;
@@ -301,7 +301,7 @@ xfs_inobt_delrec(
301 rrecs = be16_to_cpu(right->bb_numrecs); 301 rrecs = be16_to_cpu(right->bb_numrecs);
302 if (lbno != NULLAGBLOCK) { 302 if (lbno != NULLAGBLOCK) {
303 xfs_btree_firstrec(tcur, level); 303 xfs_btree_firstrec(tcur, level);
304 if ((error = xfs_inobt_decrement(tcur, level, &i))) 304 if ((error = xfs_btree_decrement(tcur, level, &i)))
305 goto error0; 305 goto error0;
306 } 306 }
307 } 307 }
@@ -315,7 +315,7 @@ xfs_inobt_delrec(
315 * previous block. 315 * previous block.
316 */ 316 */
317 xfs_btree_firstrec(tcur, level); 317 xfs_btree_firstrec(tcur, level);
318 if ((error = xfs_inobt_decrement(tcur, level, &i))) 318 if ((error = xfs_btree_decrement(tcur, level, &i)))
319 goto error0; 319 goto error0;
320 xfs_btree_firstrec(tcur, level); 320 xfs_btree_firstrec(tcur, level);
321 /* 321 /*
@@ -414,7 +414,7 @@ xfs_inobt_delrec(
414 * Just return. This is probably a logic error, but it's not fatal. 414 * Just return. This is probably a logic error, but it's not fatal.
415 */ 415 */
416 else { 416 else {
417 if (level > 0 && (error = xfs_inobt_decrement(cur, level, &i))) 417 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i)))
418 return error; 418 return error;
419 *stat = 1; 419 *stat = 1;
420 return 0; 420 return 0;
@@ -1656,90 +1656,6 @@ xfs_inobt_updkey(
1656 */ 1656 */
1657 1657
1658/* 1658/*
1659 * Decrement cursor by one record at the level.
1660 * For nonzero levels the leaf-ward information is untouched.
1661 */
1662int /* error */
1663xfs_inobt_decrement(
1664 xfs_btree_cur_t *cur, /* btree cursor */
1665 int level, /* level in btree, 0 is leaf */
1666 int *stat) /* success/failure */
1667{
1668 xfs_inobt_block_t *block; /* btree block */
1669 int error;
1670 int lev; /* btree level */
1671
1672 ASSERT(level < cur->bc_nlevels);
1673 /*
1674 * Read-ahead to the left at this level.
1675 */
1676 xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
1677 /*
1678 * Decrement the ptr at this level. If we're still in the block
1679 * then we're done.
1680 */
1681 if (--cur->bc_ptrs[level] > 0) {
1682 *stat = 1;
1683 return 0;
1684 }
1685 /*
1686 * Get a pointer to the btree block.
1687 */
1688 block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[level]);
1689#ifdef DEBUG
1690 if ((error = xfs_btree_check_sblock(cur, block, level,
1691 cur->bc_bufs[level])))
1692 return error;
1693#endif
1694 /*
1695 * If we just went off the left edge of the tree, return failure.
1696 */
1697 if (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK) {
1698 *stat = 0;
1699 return 0;
1700 }
1701 /*
1702 * March up the tree decrementing pointers.
1703 * Stop when we don't go off the left edge of a block.
1704 */
1705 for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
1706 if (--cur->bc_ptrs[lev] > 0)
1707 break;
1708 /*
1709 * Read-ahead the left block, we're going to read it
1710 * in the next loop.
1711 */
1712 xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
1713 }
1714 /*
1715 * If we went off the root then we are seriously confused.
1716 */
1717 ASSERT(lev < cur->bc_nlevels);
1718 /*
1719 * Now walk back down the tree, fixing up the cursor's buffer
1720 * pointers and key numbers.
1721 */
1722 for (block = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); lev > level; ) {
1723 xfs_agblock_t agbno; /* block number of btree block */
1724 xfs_buf_t *bp; /* buffer containing btree block */
1725
1726 agbno = be32_to_cpu(*XFS_INOBT_PTR_ADDR(block, cur->bc_ptrs[lev], cur));
1727 if ((error = xfs_btree_read_bufs(cur->bc_mp, cur->bc_tp,
1728 cur->bc_private.a.agno, agbno, 0, &bp,
1729 XFS_INO_BTREE_REF)))
1730 return error;
1731 lev--;
1732 xfs_btree_setbuf(cur, lev, bp);
1733 block = XFS_BUF_TO_INOBT_BLOCK(bp);
1734 if ((error = xfs_btree_check_sblock(cur, block, lev, bp)))
1735 return error;
1736 cur->bc_ptrs[lev] = be16_to_cpu(block->bb_numrecs);
1737 }
1738 *stat = 1;
1739 return 0;
1740}
1741
1742/*
1743 * Delete the record pointed to by cur. 1659 * Delete the record pointed to by cur.
1744 * The cursor refers to the place where the record was (could be inserted) 1660 * The cursor refers to the place where the record was (could be inserted)
1745 * when the operation returns. 1661 * when the operation returns.
@@ -1765,7 +1681,7 @@ xfs_inobt_delete(
1765 if (i == 0) { 1681 if (i == 0) {
1766 for (level = 1; level < cur->bc_nlevels; level++) { 1682 for (level = 1; level < cur->bc_nlevels; level++) {
1767 if (cur->bc_ptrs[level] == 0) { 1683 if (cur->bc_ptrs[level] == 0) {
1768 if ((error = xfs_inobt_decrement(cur, level, &i))) 1684 if ((error = xfs_btree_decrement(cur, level, &i)))
1769 return error; 1685 return error;
1770 break; 1686 break;
1771 } 1687 }
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 07fed62bcb7b..84554595d281 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -117,12 +117,6 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t;
117 i, XFS_INOBT_BLOCK_MAXRECS(1, cur))) 117 i, XFS_INOBT_BLOCK_MAXRECS(1, cur)))
118 118
119/* 119/*
120 * Decrement cursor by one record at the level.
121 * For nonzero levels the leaf-ward information is untouched.
122 */
123extern int xfs_inobt_decrement(struct xfs_btree_cur *cur, int level, int *stat);
124
125/*
126 * Delete the record pointed to by cur. 120 * Delete the record pointed to by cur.
127 * The cursor refers to the place where the record was (could be inserted) 121 * The cursor refers to the place where the record was (could be inserted)
128 * when the operation returns. 122 * when the operation returns.