aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_btree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_btree.c')
-rw-r--r--fs/xfs/xfs_btree.c111
1 files changed, 66 insertions, 45 deletions
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index e53e317b1582..db010408d701 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -266,9 +266,13 @@ xfs_btree_dup_cursor(
266 for (i = 0; i < new->bc_nlevels; i++) { 266 for (i = 0; i < new->bc_nlevels; i++) {
267 new->bc_ptrs[i] = cur->bc_ptrs[i]; 267 new->bc_ptrs[i] = cur->bc_ptrs[i];
268 new->bc_ra[i] = cur->bc_ra[i]; 268 new->bc_ra[i] = cur->bc_ra[i];
269 if ((bp = cur->bc_bufs[i])) { 269 bp = cur->bc_bufs[i];
270 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 270 if (bp) {
271 XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) { 271 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
272 XFS_BUF_ADDR(bp), mp->m_bsize,
273 0, &bp,
274 cur->bc_ops->buf_ops);
275 if (error) {
272 xfs_btree_del_cursor(new, error); 276 xfs_btree_del_cursor(new, error);
273 *ncur = NULL; 277 *ncur = NULL;
274 return error; 278 return error;
@@ -609,25 +613,26 @@ xfs_btree_offsets(
609 * Get a buffer for the block, return it read in. 613 * Get a buffer for the block, return it read in.
610 * Long-form addressing. 614 * Long-form addressing.
611 */ 615 */
612int /* error */ 616int
613xfs_btree_read_bufl( 617xfs_btree_read_bufl(
614 xfs_mount_t *mp, /* file system mount point */ 618 struct xfs_mount *mp, /* file system mount point */
615 xfs_trans_t *tp, /* transaction pointer */ 619 struct xfs_trans *tp, /* transaction pointer */
616 xfs_fsblock_t fsbno, /* file system block number */ 620 xfs_fsblock_t fsbno, /* file system block number */
617 uint lock, /* lock flags for read_buf */ 621 uint lock, /* lock flags for read_buf */
618 xfs_buf_t **bpp, /* buffer for fsbno */ 622 struct xfs_buf **bpp, /* buffer for fsbno */
619 int refval) /* ref count value for buffer */ 623 int refval, /* ref count value for buffer */
620{ 624 const struct xfs_buf_ops *ops)
621 xfs_buf_t *bp; /* return value */ 625{
626 struct xfs_buf *bp; /* return value */
622 xfs_daddr_t d; /* real disk block address */ 627 xfs_daddr_t d; /* real disk block address */
623 int error; 628 int error;
624 629
625 ASSERT(fsbno != NULLFSBLOCK); 630 ASSERT(fsbno != NULLFSBLOCK);
626 d = XFS_FSB_TO_DADDR(mp, fsbno); 631 d = XFS_FSB_TO_DADDR(mp, fsbno);
627 if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 632 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
628 mp->m_bsize, lock, &bp))) { 633 mp->m_bsize, lock, &bp, ops);
634 if (error)
629 return error; 635 return error;
630 }
631 ASSERT(!xfs_buf_geterror(bp)); 636 ASSERT(!xfs_buf_geterror(bp));
632 if (bp) 637 if (bp)
633 xfs_buf_set_ref(bp, refval); 638 xfs_buf_set_ref(bp, refval);
@@ -642,15 +647,16 @@ xfs_btree_read_bufl(
642/* ARGSUSED */ 647/* ARGSUSED */
643void 648void
644xfs_btree_reada_bufl( 649xfs_btree_reada_bufl(
645 xfs_mount_t *mp, /* file system mount point */ 650 struct xfs_mount *mp, /* file system mount point */
646 xfs_fsblock_t fsbno, /* file system block number */ 651 xfs_fsblock_t fsbno, /* file system block number */
647 xfs_extlen_t count) /* count of filesystem blocks */ 652 xfs_extlen_t count, /* count of filesystem blocks */
653 const struct xfs_buf_ops *ops)
648{ 654{
649 xfs_daddr_t d; 655 xfs_daddr_t d;
650 656
651 ASSERT(fsbno != NULLFSBLOCK); 657 ASSERT(fsbno != NULLFSBLOCK);
652 d = XFS_FSB_TO_DADDR(mp, fsbno); 658 d = XFS_FSB_TO_DADDR(mp, fsbno);
653 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count); 659 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
654} 660}
655 661
656/* 662/*
@@ -660,17 +666,18 @@ xfs_btree_reada_bufl(
660/* ARGSUSED */ 666/* ARGSUSED */
661void 667void
662xfs_btree_reada_bufs( 668xfs_btree_reada_bufs(
663 xfs_mount_t *mp, /* file system mount point */ 669 struct xfs_mount *mp, /* file system mount point */
664 xfs_agnumber_t agno, /* allocation group number */ 670 xfs_agnumber_t agno, /* allocation group number */
665 xfs_agblock_t agbno, /* allocation group block number */ 671 xfs_agblock_t agbno, /* allocation group block number */
666 xfs_extlen_t count) /* count of filesystem blocks */ 672 xfs_extlen_t count, /* count of filesystem blocks */
673 const struct xfs_buf_ops *ops)
667{ 674{
668 xfs_daddr_t d; 675 xfs_daddr_t d;
669 676
670 ASSERT(agno != NULLAGNUMBER); 677 ASSERT(agno != NULLAGNUMBER);
671 ASSERT(agbno != NULLAGBLOCK); 678 ASSERT(agbno != NULLAGBLOCK);
672 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 679 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
673 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count); 680 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
674} 681}
675 682
676STATIC int 683STATIC int
@@ -684,12 +691,14 @@ xfs_btree_readahead_lblock(
684 xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib); 691 xfs_dfsbno_t right = be64_to_cpu(block->bb_u.l.bb_rightsib);
685 692
686 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { 693 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) {
687 xfs_btree_reada_bufl(cur->bc_mp, left, 1); 694 xfs_btree_reada_bufl(cur->bc_mp, left, 1,
695 cur->bc_ops->buf_ops);
688 rval++; 696 rval++;
689 } 697 }
690 698
691 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { 699 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) {
692 xfs_btree_reada_bufl(cur->bc_mp, right, 1); 700 xfs_btree_reada_bufl(cur->bc_mp, right, 1,
701 cur->bc_ops->buf_ops);
693 rval++; 702 rval++;
694 } 703 }
695 704
@@ -709,13 +718,13 @@ xfs_btree_readahead_sblock(
709 718
710 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { 719 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
711 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 720 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
712 left, 1); 721 left, 1, cur->bc_ops->buf_ops);
713 rval++; 722 rval++;
714 } 723 }
715 724
716 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { 725 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
717 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 726 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
718 right, 1); 727 right, 1, cur->bc_ops->buf_ops);
719 rval++; 728 rval++;
720 } 729 }
721 730
@@ -853,18 +862,22 @@ xfs_btree_set_sibling(
853 } 862 }
854} 863}
855 864
856STATIC void 865void
857xfs_btree_init_block( 866xfs_btree_init_block(
858 struct xfs_btree_cur *cur, 867 struct xfs_mount *mp,
859 int level, 868 struct xfs_buf *bp,
860 int numrecs, 869 __u32 magic,
861 struct xfs_btree_block *new) /* new block */ 870 __u16 level,
871 __u16 numrecs,
872 unsigned int flags)
862{ 873{
863 new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); 874 struct xfs_btree_block *new = XFS_BUF_TO_BLOCK(bp);
875
876 new->bb_magic = cpu_to_be32(magic);
864 new->bb_level = cpu_to_be16(level); 877 new->bb_level = cpu_to_be16(level);
865 new->bb_numrecs = cpu_to_be16(numrecs); 878 new->bb_numrecs = cpu_to_be16(numrecs);
866 879
867 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 880 if (flags & XFS_BTREE_LONG_PTRS) {
868 new->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO); 881 new->bb_u.l.bb_leftsib = cpu_to_be64(NULLDFSBNO);
869 new->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO); 882 new->bb_u.l.bb_rightsib = cpu_to_be64(NULLDFSBNO);
870 } else { 883 } else {
@@ -873,6 +886,17 @@ xfs_btree_init_block(
873 } 886 }
874} 887}
875 888
889STATIC void
890xfs_btree_init_block_cur(
891 struct xfs_btree_cur *cur,
892 int level,
893 int numrecs,
894 struct xfs_buf *bp)
895{
896 xfs_btree_init_block(cur->bc_mp, bp, xfs_magics[cur->bc_btnum],
897 level, numrecs, cur->bc_flags);
898}
899
876/* 900/*
877 * Return true if ptr is the last record in the btree and 901 * Return true if ptr is the last record in the btree and
878 * we need to track updateѕ to this record. The decision 902 * we need to track updateѕ to this record. The decision
@@ -972,6 +996,7 @@ xfs_btree_get_buf_block(
972 if (!*bpp) 996 if (!*bpp)
973 return ENOMEM; 997 return ENOMEM;
974 998
999 (*bpp)->b_ops = cur->bc_ops->buf_ops;
975 *block = XFS_BUF_TO_BLOCK(*bpp); 1000 *block = XFS_BUF_TO_BLOCK(*bpp);
976 return 0; 1001 return 0;
977} 1002}
@@ -998,19 +1023,15 @@ xfs_btree_read_buf_block(
998 1023
999 d = xfs_btree_ptr_to_daddr(cur, ptr); 1024 d = xfs_btree_ptr_to_daddr(cur, ptr);
1000 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, 1025 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
1001 mp->m_bsize, flags, bpp); 1026 mp->m_bsize, flags, bpp,
1027 cur->bc_ops->buf_ops);
1002 if (error) 1028 if (error)
1003 return error; 1029 return error;
1004 1030
1005 ASSERT(!xfs_buf_geterror(*bpp)); 1031 ASSERT(!xfs_buf_geterror(*bpp));
1006
1007 xfs_btree_set_refs(cur, *bpp); 1032 xfs_btree_set_refs(cur, *bpp);
1008 *block = XFS_BUF_TO_BLOCK(*bpp); 1033 *block = XFS_BUF_TO_BLOCK(*bpp);
1009 1034 return 0;
1010 error = xfs_btree_check_block(cur, *block, level, *bpp);
1011 if (error)
1012 xfs_trans_brelse(cur->bc_tp, *bpp);
1013 return error;
1014} 1035}
1015 1036
1016/* 1037/*
@@ -2183,7 +2204,7 @@ xfs_btree_split(
2183 goto error0; 2204 goto error0;
2184 2205
2185 /* Fill in the btree header for the new right block. */ 2206 /* Fill in the btree header for the new right block. */
2186 xfs_btree_init_block(cur, xfs_btree_get_level(left), 0, right); 2207 xfs_btree_init_block_cur(cur, xfs_btree_get_level(left), 0, rbp);
2187 2208
2188 /* 2209 /*
2189 * Split the entries between the old and the new block evenly. 2210 * Split the entries between the old and the new block evenly.
@@ -2492,7 +2513,7 @@ xfs_btree_new_root(
2492 nptr = 2; 2513 nptr = 2;
2493 } 2514 }
2494 /* Fill in the new block's btree header and log it. */ 2515 /* Fill in the new block's btree header and log it. */
2495 xfs_btree_init_block(cur, cur->bc_nlevels, 2, new); 2516 xfs_btree_init_block_cur(cur, cur->bc_nlevels, 2, nbp);
2496 xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); 2517 xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS);
2497 ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) && 2518 ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) &&
2498 !xfs_btree_ptr_is_null(cur, &rptr)); 2519 !xfs_btree_ptr_is_null(cur, &rptr));