diff options
Diffstat (limited to 'fs/xfs/xfs_btree.c')
| -rw-r--r-- | fs/xfs/xfs_btree.c | 111 |
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 | */ |
| 612 | int /* error */ | 616 | int |
| 613 | xfs_btree_read_bufl( | 617 | xfs_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 */ |
| 643 | void | 648 | void |
| 644 | xfs_btree_reada_bufl( | 649 | xfs_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 */ |
| 661 | void | 667 | void |
| 662 | xfs_btree_reada_bufs( | 668 | xfs_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 | ||
| 676 | STATIC int | 683 | STATIC 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 | ||
| 856 | STATIC void | 865 | void |
| 857 | xfs_btree_init_block( | 866 | xfs_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 | ||
| 889 | STATIC void | ||
| 890 | xfs_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)); |
