diff options
Diffstat (limited to 'fs/xfs/xfs_btree.c')
-rw-r--r-- | fs/xfs/xfs_btree.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 59796b42e9c4..4d793e4ccdcc 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -725,66 +725,84 @@ xfs_btree_reada_bufs( | |||
725 | xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count); | 725 | xfs_baread(mp->m_ddev_targp, d, mp->m_bsize * count); |
726 | } | 726 | } |
727 | 727 | ||
728 | STATIC int | ||
729 | xfs_btree_readahead_lblock( | ||
730 | struct xfs_btree_cur *cur, | ||
731 | int lr, | ||
732 | struct xfs_btree_block *block) | ||
733 | { | ||
734 | int rval = 0; | ||
735 | xfs_fsblock_t left = be64_to_cpu(block->bb_u.l.bb_leftsib); | ||
736 | xfs_fsblock_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); | ||
737 | |||
738 | if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { | ||
739 | xfs_btree_reada_bufl(cur->bc_mp, left, 1); | ||
740 | rval++; | ||
741 | } | ||
742 | |||
743 | if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { | ||
744 | xfs_btree_reada_bufl(cur->bc_mp, right, 1); | ||
745 | rval++; | ||
746 | } | ||
747 | |||
748 | return rval; | ||
749 | } | ||
750 | |||
751 | STATIC int | ||
752 | xfs_btree_readahead_sblock( | ||
753 | struct xfs_btree_cur *cur, | ||
754 | int lr, | ||
755 | struct xfs_btree_block *block) | ||
756 | { | ||
757 | int rval = 0; | ||
758 | xfs_agblock_t left = be32_to_cpu(block->bb_u.s.bb_leftsib); | ||
759 | xfs_agblock_t right = be32_to_cpu(block->bb_u.s.bb_rightsib); | ||
760 | |||
761 | |||
762 | if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { | ||
763 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
764 | left, 1); | ||
765 | rval++; | ||
766 | } | ||
767 | |||
768 | if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { | ||
769 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
770 | right, 1); | ||
771 | rval++; | ||
772 | } | ||
773 | |||
774 | return rval; | ||
775 | } | ||
776 | |||
728 | /* | 777 | /* |
729 | * Read-ahead btree blocks, at the given level. | 778 | * Read-ahead btree blocks, at the given level. |
730 | * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA. | 779 | * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA. |
731 | */ | 780 | */ |
732 | int | 781 | int |
733 | xfs_btree_readahead_core( | 782 | xfs_btree_readahead( |
734 | xfs_btree_cur_t *cur, /* btree cursor */ | 783 | struct xfs_btree_cur *cur, /* btree cursor */ |
735 | int lev, /* level in btree */ | 784 | int lev, /* level in btree */ |
736 | int lr) /* left/right bits */ | 785 | int lr) /* left/right bits */ |
737 | { | 786 | { |
738 | xfs_alloc_block_t *a; | 787 | struct xfs_btree_block *block; |
739 | xfs_bmbt_block_t *b; | 788 | |
740 | xfs_inobt_block_t *i; | 789 | /* |
741 | int rval = 0; | 790 | * No readahead needed if we are at the root level and the |
791 | * btree root is stored in the inode. | ||
792 | */ | ||
793 | if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && | ||
794 | (lev == cur->bc_nlevels - 1)) | ||
795 | return 0; | ||
796 | |||
797 | if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev]) | ||
798 | return 0; | ||
742 | 799 | ||
743 | ASSERT(cur->bc_bufs[lev] != NULL); | ||
744 | cur->bc_ra[lev] |= lr; | 800 | cur->bc_ra[lev] |= lr; |
745 | switch (cur->bc_btnum) { | 801 | block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]); |
746 | case XFS_BTNUM_BNO: | 802 | |
747 | case XFS_BTNUM_CNT: | 803 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
748 | a = XFS_BUF_TO_ALLOC_BLOCK(cur->bc_bufs[lev]); | 804 | return xfs_btree_readahead_lblock(cur, lr, block); |
749 | if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(a->bb_leftsib) != NULLAGBLOCK) { | 805 | return xfs_btree_readahead_sblock(cur, lr, block); |
750 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
751 | be32_to_cpu(a->bb_leftsib), 1); | ||
752 | rval++; | ||
753 | } | ||
754 | if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(a->bb_rightsib) != NULLAGBLOCK) { | ||
755 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
756 | be32_to_cpu(a->bb_rightsib), 1); | ||
757 | rval++; | ||
758 | } | ||
759 | break; | ||
760 | case XFS_BTNUM_BMAP: | ||
761 | b = XFS_BUF_TO_BMBT_BLOCK(cur->bc_bufs[lev]); | ||
762 | if ((lr & XFS_BTCUR_LEFTRA) && be64_to_cpu(b->bb_leftsib) != NULLDFSBNO) { | ||
763 | xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_leftsib), 1); | ||
764 | rval++; | ||
765 | } | ||
766 | if ((lr & XFS_BTCUR_RIGHTRA) && be64_to_cpu(b->bb_rightsib) != NULLDFSBNO) { | ||
767 | xfs_btree_reada_bufl(cur->bc_mp, be64_to_cpu(b->bb_rightsib), 1); | ||
768 | rval++; | ||
769 | } | ||
770 | break; | ||
771 | case XFS_BTNUM_INO: | ||
772 | i = XFS_BUF_TO_INOBT_BLOCK(cur->bc_bufs[lev]); | ||
773 | if ((lr & XFS_BTCUR_LEFTRA) && be32_to_cpu(i->bb_leftsib) != NULLAGBLOCK) { | ||
774 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
775 | be32_to_cpu(i->bb_leftsib), 1); | ||
776 | rval++; | ||
777 | } | ||
778 | if ((lr & XFS_BTCUR_RIGHTRA) && be32_to_cpu(i->bb_rightsib) != NULLAGBLOCK) { | ||
779 | xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, | ||
780 | be32_to_cpu(i->bb_rightsib), 1); | ||
781 | rval++; | ||
782 | } | ||
783 | break; | ||
784 | default: | ||
785 | ASSERT(0); | ||
786 | } | ||
787 | return rval; | ||
788 | } | 806 | } |
789 | 807 | ||
790 | /* | 808 | /* |