diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 01:57:51 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 01:57:51 -0400 |
commit | d4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0 (patch) | |
tree | cd0b5a46d81fa9d9b0253c489f64ad698e3a0fa9 /fs/xfs/xfs_bmap_btree.c | |
parent | 4b22a57188d87e873346b73c227607715be96399 (diff) |
[XFS] move xfs_bmbt_killroot to common code
xfs_bmbt_killroot is a mostly generic implementation of moving from a real
block based root to an inode based root. So move it to xfs_btree.c where
it can use all the nice infrastructure there and make it pointer size
agnostic
The new name for it is xfs_btree_kill_iroot, following the old naming but
making it clear we're dealing with the root in inode case here, and to
avoid confusion with xfs_btree_new_root which is used for the not inode
rooted case. I've also added a comment describing what it does and why
it's named the way it is.
SGI-PV: 985583
SGI-Modid: xfs-linux-melb:xfs-kern:32203a
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 | 116 |
1 files changed, 22 insertions, 94 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 2b15df32b7d2..6b7774ebc26a 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -49,7 +49,6 @@ | |||
49 | */ | 49 | */ |
50 | 50 | ||
51 | 51 | ||
52 | STATIC int xfs_bmbt_killroot(xfs_btree_cur_t *); | ||
53 | STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); | 52 | STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); |
54 | STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); | 53 | STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); |
55 | 54 | ||
@@ -194,7 +193,7 @@ xfs_bmbt_delrec( | |||
194 | if (level == cur->bc_nlevels - 1) { | 193 | if (level == cur->bc_nlevels - 1) { |
195 | xfs_iroot_realloc(cur->bc_private.b.ip, -1, | 194 | xfs_iroot_realloc(cur->bc_private.b.ip, -1, |
196 | cur->bc_private.b.whichfork); | 195 | cur->bc_private.b.whichfork); |
197 | if ((error = xfs_bmbt_killroot(cur))) { | 196 | if ((error = xfs_btree_kill_iroot(cur))) { |
198 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 197 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
199 | goto error0; | 198 | goto error0; |
200 | } | 199 | } |
@@ -228,7 +227,7 @@ xfs_bmbt_delrec( | |||
228 | */ | 227 | */ |
229 | if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK && | 228 | if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK && |
230 | level == cur->bc_nlevels - 2) { | 229 | level == cur->bc_nlevels - 2) { |
231 | if ((error = xfs_bmbt_killroot(cur))) { | 230 | if ((error = xfs_btree_kill_iroot(cur))) { |
232 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 231 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
233 | goto error0; | 232 | goto error0; |
234 | } | 233 | } |
@@ -456,97 +455,6 @@ error0: | |||
456 | return error; | 455 | return error; |
457 | } | 456 | } |
458 | 457 | ||
459 | STATIC int | ||
460 | xfs_bmbt_killroot( | ||
461 | xfs_btree_cur_t *cur) | ||
462 | { | ||
463 | xfs_bmbt_block_t *block; | ||
464 | xfs_bmbt_block_t *cblock; | ||
465 | xfs_buf_t *cbp; | ||
466 | xfs_bmbt_key_t *ckp; | ||
467 | xfs_bmbt_ptr_t *cpp; | ||
468 | #ifdef DEBUG | ||
469 | int error; | ||
470 | #endif | ||
471 | int i; | ||
472 | xfs_bmbt_key_t *kp; | ||
473 | xfs_inode_t *ip; | ||
474 | xfs_ifork_t *ifp; | ||
475 | int level; | ||
476 | xfs_bmbt_ptr_t *pp; | ||
477 | |||
478 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | ||
479 | level = cur->bc_nlevels - 1; | ||
480 | ASSERT(level >= 1); | ||
481 | /* | ||
482 | * Don't deal with the root block needs to be a leaf case. | ||
483 | * We're just going to turn the thing back into extents anyway. | ||
484 | */ | ||
485 | if (level == 1) { | ||
486 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
487 | return 0; | ||
488 | } | ||
489 | block = xfs_bmbt_get_block(cur, level, &cbp); | ||
490 | /* | ||
491 | * Give up if the root has multiple children. | ||
492 | */ | ||
493 | if (be16_to_cpu(block->bb_numrecs) != 1) { | ||
494 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
495 | return 0; | ||
496 | } | ||
497 | /* | ||
498 | * Only do this if the next level will fit. | ||
499 | * Then the data must be copied up to the inode, | ||
500 | * instead of freeing the root you free the next level. | ||
501 | */ | ||
502 | cbp = cur->bc_bufs[level - 1]; | ||
503 | cblock = XFS_BUF_TO_BMBT_BLOCK(cbp); | ||
504 | if (be16_to_cpu(cblock->bb_numrecs) > XFS_BMAP_BLOCK_DMAXRECS(level, cur)) { | ||
505 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
506 | return 0; | ||
507 | } | ||
508 | ASSERT(be64_to_cpu(cblock->bb_leftsib) == NULLDFSBNO); | ||
509 | ASSERT(be64_to_cpu(cblock->bb_rightsib) == NULLDFSBNO); | ||
510 | ip = cur->bc_private.b.ip; | ||
511 | ifp = XFS_IFORK_PTR(ip, cur->bc_private.b.whichfork); | ||
512 | ASSERT(XFS_BMAP_BLOCK_IMAXRECS(level, cur) == | ||
513 | XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes)); | ||
514 | i = (int)(be16_to_cpu(cblock->bb_numrecs) - XFS_BMAP_BLOCK_IMAXRECS(level, cur)); | ||
515 | if (i) { | ||
516 | xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork); | ||
517 | block = ifp->if_broot; | ||
518 | } | ||
519 | be16_add_cpu(&block->bb_numrecs, i); | ||
520 | ASSERT(block->bb_numrecs == cblock->bb_numrecs); | ||
521 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); | ||
522 | ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); | ||
523 | memcpy(kp, ckp, be16_to_cpu(block->bb_numrecs) * sizeof(*kp)); | ||
524 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); | ||
525 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); | ||
526 | #ifdef DEBUG | ||
527 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { | ||
528 | if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) { | ||
529 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | ||
530 | return error; | ||
531 | } | ||
532 | } | ||
533 | #endif | ||
534 | memcpy(pp, cpp, be16_to_cpu(block->bb_numrecs) * sizeof(*pp)); | ||
535 | xfs_bmap_add_free(XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(cbp)), 1, | ||
536 | cur->bc_private.b.flist, cur->bc_mp); | ||
537 | ip->i_d.di_nblocks--; | ||
538 | XFS_TRANS_MOD_DQUOT_BYINO(cur->bc_mp, cur->bc_tp, ip, | ||
539 | XFS_TRANS_DQ_BCOUNT, -1L); | ||
540 | xfs_trans_binval(cur->bc_tp, cbp); | ||
541 | cur->bc_bufs[level - 1] = NULL; | ||
542 | be16_add_cpu(&block->bb_level, -1); | ||
543 | xfs_trans_log_inode(cur->bc_tp, ip, | ||
544 | XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); | ||
545 | cur->bc_nlevels--; | ||
546 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | ||
547 | return 0; | ||
548 | } | ||
549 | |||
550 | /* | 458 | /* |
551 | * Log key values from the btree block. | 459 | * Log key values from the btree block. |
552 | */ | 460 | */ |
@@ -1299,6 +1207,25 @@ xfs_bmbt_alloc_block( | |||
1299 | } | 1207 | } |
1300 | 1208 | ||
1301 | STATIC int | 1209 | STATIC int |
1210 | xfs_bmbt_free_block( | ||
1211 | struct xfs_btree_cur *cur, | ||
1212 | struct xfs_buf *bp) | ||
1213 | { | ||
1214 | struct xfs_mount *mp = cur->bc_mp; | ||
1215 | struct xfs_inode *ip = cur->bc_private.b.ip; | ||
1216 | struct xfs_trans *tp = cur->bc_tp; | ||
1217 | xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); | ||
1218 | |||
1219 | xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp); | ||
1220 | ip->i_d.di_nblocks--; | ||
1221 | |||
1222 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1223 | XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); | ||
1224 | xfs_trans_binval(tp, bp); | ||
1225 | return 0; | ||
1226 | } | ||
1227 | |||
1228 | STATIC int | ||
1302 | xfs_bmbt_get_maxrecs( | 1229 | xfs_bmbt_get_maxrecs( |
1303 | struct xfs_btree_cur *cur, | 1230 | struct xfs_btree_cur *cur, |
1304 | int level) | 1231 | int level) |
@@ -1460,6 +1387,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { | |||
1460 | .dup_cursor = xfs_bmbt_dup_cursor, | 1387 | .dup_cursor = xfs_bmbt_dup_cursor, |
1461 | .update_cursor = xfs_bmbt_update_cursor, | 1388 | .update_cursor = xfs_bmbt_update_cursor, |
1462 | .alloc_block = xfs_bmbt_alloc_block, | 1389 | .alloc_block = xfs_bmbt_alloc_block, |
1390 | .free_block = xfs_bmbt_free_block, | ||
1463 | .get_maxrecs = xfs_bmbt_get_maxrecs, | 1391 | .get_maxrecs = xfs_bmbt_get_maxrecs, |
1464 | .get_dmaxrecs = xfs_bmbt_get_dmaxrecs, | 1392 | .get_dmaxrecs = xfs_bmbt_get_dmaxrecs, |
1465 | .init_key_from_rec = xfs_bmbt_init_key_from_rec, | 1393 | .init_key_from_rec = xfs_bmbt_init_key_from_rec, |