diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_btree.c')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index c5eeb3241e25..853828c6b45e 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -66,6 +66,7 @@ xfs_extent_state( | |||
66 | */ | 66 | */ |
67 | void | 67 | void |
68 | xfs_bmdr_to_bmbt( | 68 | xfs_bmdr_to_bmbt( |
69 | struct xfs_mount *mp, | ||
69 | xfs_bmdr_block_t *dblock, | 70 | xfs_bmdr_block_t *dblock, |
70 | int dblocklen, | 71 | int dblocklen, |
71 | xfs_bmbt_block_t *rblock, | 72 | xfs_bmbt_block_t *rblock, |
@@ -83,11 +84,11 @@ xfs_bmdr_to_bmbt( | |||
83 | rblock->bb_numrecs = dblock->bb_numrecs; | 84 | rblock->bb_numrecs = dblock->bb_numrecs; |
84 | rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO); | 85 | rblock->bb_leftsib = cpu_to_be64(NULLDFSBNO); |
85 | rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO); | 86 | rblock->bb_rightsib = cpu_to_be64(NULLDFSBNO); |
86 | dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); | 87 | dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); |
87 | fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); | 88 | fkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); |
88 | tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); | 89 | tkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); |
89 | fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); | 90 | fpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); |
90 | tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); | 91 | tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); |
91 | dmxr = be16_to_cpu(dblock->bb_numrecs); | 92 | dmxr = be16_to_cpu(dblock->bb_numrecs); |
92 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); | 93 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); |
93 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); | 94 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); |
@@ -428,6 +429,7 @@ xfs_bmbt_set_state( | |||
428 | */ | 429 | */ |
429 | void | 430 | void |
430 | xfs_bmbt_to_bmdr( | 431 | xfs_bmbt_to_bmdr( |
432 | struct xfs_mount *mp, | ||
431 | xfs_bmbt_block_t *rblock, | 433 | xfs_bmbt_block_t *rblock, |
432 | int rblocklen, | 434 | int rblocklen, |
433 | xfs_bmdr_block_t *dblock, | 435 | xfs_bmdr_block_t *dblock, |
@@ -445,10 +447,10 @@ xfs_bmbt_to_bmdr( | |||
445 | ASSERT(be16_to_cpu(rblock->bb_level) > 0); | 447 | ASSERT(be16_to_cpu(rblock->bb_level) > 0); |
446 | dblock->bb_level = rblock->bb_level; | 448 | dblock->bb_level = rblock->bb_level; |
447 | dblock->bb_numrecs = rblock->bb_numrecs; | 449 | dblock->bb_numrecs = rblock->bb_numrecs; |
448 | dmxr = (int)XFS_BTREE_BLOCK_MAXRECS(dblocklen, xfs_bmdr, 0); | 450 | dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); |
449 | fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); | 451 | fkp = XFS_BMAP_BROOT_KEY_ADDR(rblock, 1, rblocklen); |
450 | tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); | 452 | tkp = XFS_BTREE_KEY_ADDR(xfs_bmdr, dblock, 1); |
451 | fpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); | 453 | fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); |
452 | tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); | 454 | tpp = XFS_BTREE_PTR_ADDR(xfs_bmdr, dblock, 1, dmxr); |
453 | dmxr = be16_to_cpu(dblock->bb_numrecs); | 455 | dmxr = be16_to_cpu(dblock->bb_numrecs); |
454 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); | 456 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); |
@@ -626,15 +628,36 @@ xfs_bmbt_get_minrecs( | |||
626 | struct xfs_btree_cur *cur, | 628 | struct xfs_btree_cur *cur, |
627 | int level) | 629 | int level) |
628 | { | 630 | { |
629 | return XFS_BMAP_BLOCK_IMINRECS(level, cur); | 631 | if (level == cur->bc_nlevels - 1) { |
632 | struct xfs_ifork *ifp; | ||
633 | |||
634 | ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, | ||
635 | cur->bc_private.b.whichfork); | ||
636 | |||
637 | return xfs_bmbt_maxrecs(cur->bc_mp, | ||
638 | ifp->if_broot_bytes, level == 0) / 2; | ||
639 | } | ||
640 | |||
641 | return cur->bc_mp->m_bmap_dmnr[level != 0]; | ||
630 | } | 642 | } |
631 | 643 | ||
632 | STATIC int | 644 | int |
633 | xfs_bmbt_get_maxrecs( | 645 | xfs_bmbt_get_maxrecs( |
634 | struct xfs_btree_cur *cur, | 646 | struct xfs_btree_cur *cur, |
635 | int level) | 647 | int level) |
636 | { | 648 | { |
637 | return XFS_BMAP_BLOCK_IMAXRECS(level, cur); | 649 | if (level == cur->bc_nlevels - 1) { |
650 | struct xfs_ifork *ifp; | ||
651 | |||
652 | ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, | ||
653 | cur->bc_private.b.whichfork); | ||
654 | |||
655 | return xfs_bmbt_maxrecs(cur->bc_mp, | ||
656 | ifp->if_broot_bytes, level == 0); | ||
657 | } | ||
658 | |||
659 | return cur->bc_mp->m_bmap_dmxr[level != 0]; | ||
660 | |||
638 | } | 661 | } |
639 | 662 | ||
640 | /* | 663 | /* |
@@ -651,7 +674,10 @@ xfs_bmbt_get_dmaxrecs( | |||
651 | struct xfs_btree_cur *cur, | 674 | struct xfs_btree_cur *cur, |
652 | int level) | 675 | int level) |
653 | { | 676 | { |
654 | return XFS_BMAP_BLOCK_DMAXRECS(level, cur); | 677 | if (level != cur->bc_nlevels - 1) |
678 | return cur->bc_mp->m_bmap_dmxr[level != 0]; | ||
679 | return xfs_bmdr_maxrecs(cur->bc_mp, cur->bc_private.b.forksize, | ||
680 | level == 0); | ||
655 | } | 681 | } |
656 | 682 | ||
657 | STATIC void | 683 | STATIC void |
@@ -871,3 +897,35 @@ xfs_bmbt_init_cursor( | |||
871 | 897 | ||
872 | return cur; | 898 | return cur; |
873 | } | 899 | } |
900 | |||
901 | /* | ||
902 | * Calculate number of records in a bmap btree block. | ||
903 | */ | ||
904 | int | ||
905 | xfs_bmbt_maxrecs( | ||
906 | struct xfs_mount *mp, | ||
907 | int blocklen, | ||
908 | int leaf) | ||
909 | { | ||
910 | blocklen -= sizeof(struct xfs_btree_lblock); | ||
911 | |||
912 | if (leaf) | ||
913 | return blocklen / sizeof(xfs_bmbt_rec_t); | ||
914 | return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)); | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * Calculate number of records in a bmap btree inode root. | ||
919 | */ | ||
920 | int | ||
921 | xfs_bmdr_maxrecs( | ||
922 | struct xfs_mount *mp, | ||
923 | int blocklen, | ||
924 | int leaf) | ||
925 | { | ||
926 | blocklen -= sizeof(xfs_bmdr_block_t); | ||
927 | |||
928 | if (leaf) | ||
929 | return blocklen / sizeof(xfs_bmdr_rec_t); | ||
930 | return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t)); | ||
931 | } | ||