| .. | .. |
|---|
| 11 | 11 | #include "xfs_trans_resv.h" |
|---|
| 12 | 12 | #include "xfs_bit.h" |
|---|
| 13 | 13 | #include "xfs_mount.h" |
|---|
| 14 | | -#include "xfs_defer.h" |
|---|
| 15 | 14 | #include "xfs_inode.h" |
|---|
| 16 | 15 | #include "xfs_trans.h" |
|---|
| 17 | | -#include "xfs_inode_item.h" |
|---|
| 18 | 16 | #include "xfs_buf_item.h" |
|---|
| 19 | 17 | #include "xfs_btree.h" |
|---|
| 20 | 18 | #include "xfs_errortag.h" |
|---|
| 21 | 19 | #include "xfs_error.h" |
|---|
| 22 | 20 | #include "xfs_trace.h" |
|---|
| 23 | | -#include "xfs_cksum.h" |
|---|
| 24 | 21 | #include "xfs_alloc.h" |
|---|
| 25 | 22 | #include "xfs_log.h" |
|---|
| 23 | +#include "xfs_btree_staging.h" |
|---|
| 26 | 24 | |
|---|
| 27 | 25 | /* |
|---|
| 28 | 26 | * Cursor allocation zone. |
|---|
| .. | .. |
|---|
| 108 | 106 | xfs_failaddr_t fa; |
|---|
| 109 | 107 | |
|---|
| 110 | 108 | fa = __xfs_btree_check_lblock(cur, block, level, bp); |
|---|
| 111 | | - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, |
|---|
| 112 | | - XFS_ERRTAG_BTREE_CHECK_LBLOCK))) { |
|---|
| 109 | + if (XFS_IS_CORRUPT(mp, fa != NULL) || |
|---|
| 110 | + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) { |
|---|
| 113 | 111 | if (bp) |
|---|
| 114 | 112 | trace_xfs_btree_corrupt(bp, _RET_IP_); |
|---|
| 115 | | - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
|---|
| 116 | 113 | return -EFSCORRUPTED; |
|---|
| 117 | 114 | } |
|---|
| 118 | 115 | return 0; |
|---|
| .. | .. |
|---|
| 172 | 169 | xfs_failaddr_t fa; |
|---|
| 173 | 170 | |
|---|
| 174 | 171 | fa = __xfs_btree_check_sblock(cur, block, level, bp); |
|---|
| 175 | | - if (unlikely(XFS_TEST_ERROR(fa != NULL, mp, |
|---|
| 176 | | - XFS_ERRTAG_BTREE_CHECK_SBLOCK))) { |
|---|
| 172 | + if (XFS_IS_CORRUPT(mp, fa != NULL) || |
|---|
| 173 | + XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) { |
|---|
| 177 | 174 | if (bp) |
|---|
| 178 | 175 | trace_xfs_btree_corrupt(bp, _RET_IP_); |
|---|
| 179 | | - XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp); |
|---|
| 180 | 176 | return -EFSCORRUPTED; |
|---|
| 181 | 177 | } |
|---|
| 182 | 178 | return 0; |
|---|
| .. | .. |
|---|
| 219 | 215 | { |
|---|
| 220 | 216 | if (level <= 0) |
|---|
| 221 | 217 | return false; |
|---|
| 222 | | - return xfs_verify_agbno(cur->bc_mp, cur->bc_private.a.agno, agbno); |
|---|
| 218 | + return xfs_verify_agbno(cur->bc_mp, cur->bc_ag.agno, agbno); |
|---|
| 223 | 219 | } |
|---|
| 224 | 220 | |
|---|
| 225 | 221 | /* |
|---|
| .. | .. |
|---|
| 239 | 235 | return 0; |
|---|
| 240 | 236 | xfs_err(cur->bc_mp, |
|---|
| 241 | 237 | "Inode %llu fork %d: Corrupt btree %d pointer at level %d index %d.", |
|---|
| 242 | | - cur->bc_private.b.ip->i_ino, |
|---|
| 243 | | - cur->bc_private.b.whichfork, cur->bc_btnum, |
|---|
| 238 | + cur->bc_ino.ip->i_ino, |
|---|
| 239 | + cur->bc_ino.whichfork, cur->bc_btnum, |
|---|
| 244 | 240 | level, index); |
|---|
| 245 | 241 | } else { |
|---|
| 246 | 242 | if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]), |
|---|
| .. | .. |
|---|
| 248 | 244 | return 0; |
|---|
| 249 | 245 | xfs_err(cur->bc_mp, |
|---|
| 250 | 246 | "AG %u: Corrupt btree %d pointer at level %d index %d.", |
|---|
| 251 | | - cur->bc_private.a.agno, cur->bc_btnum, |
|---|
| 247 | + cur->bc_ag.agno, cur->bc_btnum, |
|---|
| 252 | 248 | level, index); |
|---|
| 253 | 249 | } |
|---|
| 254 | 250 | |
|---|
| .. | .. |
|---|
| 276 | 272 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 277 | 273 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 278 | 274 | |
|---|
| 279 | | - if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) |
|---|
| 275 | + if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb)) |
|---|
| 280 | 276 | return; |
|---|
| 281 | 277 | if (bip) |
|---|
| 282 | 278 | block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| .. | .. |
|---|
| 288 | 284 | struct xfs_buf *bp) |
|---|
| 289 | 285 | { |
|---|
| 290 | 286 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 291 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 287 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 292 | 288 | |
|---|
| 293 | 289 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 294 | 290 | if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn))) |
|---|
| .. | .. |
|---|
| 314 | 310 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 315 | 311 | struct xfs_buf_log_item *bip = bp->b_log_item; |
|---|
| 316 | 312 | |
|---|
| 317 | | - if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) |
|---|
| 313 | + if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb)) |
|---|
| 318 | 314 | return; |
|---|
| 319 | 315 | if (bip) |
|---|
| 320 | 316 | block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn); |
|---|
| .. | .. |
|---|
| 326 | 322 | struct xfs_buf *bp) |
|---|
| 327 | 323 | { |
|---|
| 328 | 324 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 329 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 325 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 330 | 326 | |
|---|
| 331 | 327 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
|---|
| 332 | 328 | if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn))) |
|---|
| .. | .. |
|---|
| 357 | 353 | */ |
|---|
| 358 | 354 | void |
|---|
| 359 | 355 | xfs_btree_del_cursor( |
|---|
| 360 | | - xfs_btree_cur_t *cur, /* btree cursor */ |
|---|
| 361 | | - int error) /* del because of error */ |
|---|
| 356 | + struct xfs_btree_cur *cur, /* btree cursor */ |
|---|
| 357 | + int error) /* del because of error */ |
|---|
| 362 | 358 | { |
|---|
| 363 | | - int i; /* btree level */ |
|---|
| 359 | + int i; /* btree level */ |
|---|
| 364 | 360 | |
|---|
| 365 | 361 | /* |
|---|
| 366 | | - * Clear the buffer pointers, and release the buffers. |
|---|
| 367 | | - * If we're doing this in the face of an error, we |
|---|
| 368 | | - * need to make sure to inspect all of the entries |
|---|
| 369 | | - * in the bc_bufs array for buffers to be unlocked. |
|---|
| 370 | | - * This is because some of the btree code works from |
|---|
| 371 | | - * level n down to 0, and if we get an error along |
|---|
| 372 | | - * the way we won't have initialized all the entries |
|---|
| 373 | | - * down to 0. |
|---|
| 362 | + * Clear the buffer pointers and release the buffers. If we're doing |
|---|
| 363 | + * this because of an error, inspect all of the entries in the bc_bufs |
|---|
| 364 | + * array for buffers to be unlocked. This is because some of the btree |
|---|
| 365 | + * code works from level n down to 0, and if we get an error along the |
|---|
| 366 | + * way we won't have initialized all the entries down to 0. |
|---|
| 374 | 367 | */ |
|---|
| 375 | 368 | for (i = 0; i < cur->bc_nlevels; i++) { |
|---|
| 376 | 369 | if (cur->bc_bufs[i]) |
|---|
| .. | .. |
|---|
| 378 | 371 | else if (!error) |
|---|
| 379 | 372 | break; |
|---|
| 380 | 373 | } |
|---|
| 374 | + |
|---|
| 381 | 375 | /* |
|---|
| 382 | | - * Can't free a bmap cursor without having dealt with the |
|---|
| 383 | | - * allocated indirect blocks' accounting. |
|---|
| 376 | + * If we are doing a BMBT update, the number of unaccounted blocks |
|---|
| 377 | + * allocated during this cursor life time should be zero. If it's not |
|---|
| 378 | + * zero, then we should be shut down or on our way to shutdown due to |
|---|
| 379 | + * cancelling a dirty transaction on error. |
|---|
| 384 | 380 | */ |
|---|
| 385 | | - ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || |
|---|
| 386 | | - cur->bc_private.b.allocated == 0); |
|---|
| 387 | | - /* |
|---|
| 388 | | - * Free the cursor. |
|---|
| 389 | | - */ |
|---|
| 390 | | - kmem_zone_free(xfs_btree_cur_zone, cur); |
|---|
| 381 | + ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 || |
|---|
| 382 | + XFS_FORCED_SHUTDOWN(cur->bc_mp) || error != 0); |
|---|
| 383 | + if (unlikely(cur->bc_flags & XFS_BTREE_STAGING)) |
|---|
| 384 | + kmem_free(cur->bc_ops); |
|---|
| 385 | + kmem_cache_free(xfs_btree_cur_zone, cur); |
|---|
| 391 | 386 | } |
|---|
| 392 | 387 | |
|---|
| 393 | 388 | /* |
|---|
| .. | .. |
|---|
| 647 | 642 | ((char *)block + xfs_btree_ptr_offset(cur, n, level)); |
|---|
| 648 | 643 | } |
|---|
| 649 | 644 | |
|---|
| 645 | +struct xfs_ifork * |
|---|
| 646 | +xfs_btree_ifork_ptr( |
|---|
| 647 | + struct xfs_btree_cur *cur) |
|---|
| 648 | +{ |
|---|
| 649 | + ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); |
|---|
| 650 | + |
|---|
| 651 | + if (cur->bc_flags & XFS_BTREE_STAGING) |
|---|
| 652 | + return cur->bc_ino.ifake->if_fork; |
|---|
| 653 | + return XFS_IFORK_PTR(cur->bc_ino.ip, cur->bc_ino.whichfork); |
|---|
| 654 | +} |
|---|
| 655 | + |
|---|
| 650 | 656 | /* |
|---|
| 651 | 657 | * Get the root block which is stored in the inode. |
|---|
| 652 | 658 | * |
|---|
| .. | .. |
|---|
| 657 | 663 | xfs_btree_get_iroot( |
|---|
| 658 | 664 | struct xfs_btree_cur *cur) |
|---|
| 659 | 665 | { |
|---|
| 660 | | - struct xfs_ifork *ifp; |
|---|
| 666 | + struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur); |
|---|
| 661 | 667 | |
|---|
| 662 | | - ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork); |
|---|
| 663 | 668 | return (struct xfs_btree_block *)ifp->if_broot; |
|---|
| 664 | 669 | } |
|---|
| 665 | 670 | |
|---|
| .. | .. |
|---|
| 681 | 686 | |
|---|
| 682 | 687 | *bpp = cur->bc_bufs[level]; |
|---|
| 683 | 688 | return XFS_BUF_TO_BLOCK(*bpp); |
|---|
| 684 | | -} |
|---|
| 685 | | - |
|---|
| 686 | | -/* |
|---|
| 687 | | - * Get a buffer for the block, return it with no data read. |
|---|
| 688 | | - * Long-form addressing. |
|---|
| 689 | | - */ |
|---|
| 690 | | -xfs_buf_t * /* buffer for fsbno */ |
|---|
| 691 | | -xfs_btree_get_bufl( |
|---|
| 692 | | - xfs_mount_t *mp, /* file system mount point */ |
|---|
| 693 | | - xfs_trans_t *tp, /* transaction pointer */ |
|---|
| 694 | | - xfs_fsblock_t fsbno, /* file system block number */ |
|---|
| 695 | | - uint lock) /* lock flags for get_buf */ |
|---|
| 696 | | -{ |
|---|
| 697 | | - xfs_daddr_t d; /* real disk block address */ |
|---|
| 698 | | - |
|---|
| 699 | | - ASSERT(fsbno != NULLFSBLOCK); |
|---|
| 700 | | - d = XFS_FSB_TO_DADDR(mp, fsbno); |
|---|
| 701 | | - return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); |
|---|
| 702 | | -} |
|---|
| 703 | | - |
|---|
| 704 | | -/* |
|---|
| 705 | | - * Get a buffer for the block, return it with no data read. |
|---|
| 706 | | - * Short-form addressing. |
|---|
| 707 | | - */ |
|---|
| 708 | | -xfs_buf_t * /* buffer for agno/agbno */ |
|---|
| 709 | | -xfs_btree_get_bufs( |
|---|
| 710 | | - xfs_mount_t *mp, /* file system mount point */ |
|---|
| 711 | | - xfs_trans_t *tp, /* transaction pointer */ |
|---|
| 712 | | - xfs_agnumber_t agno, /* allocation group number */ |
|---|
| 713 | | - xfs_agblock_t agbno, /* allocation group block number */ |
|---|
| 714 | | - uint lock) /* lock flags for get_buf */ |
|---|
| 715 | | -{ |
|---|
| 716 | | - xfs_daddr_t d; /* real disk block address */ |
|---|
| 717 | | - |
|---|
| 718 | | - ASSERT(agno != NULLAGNUMBER); |
|---|
| 719 | | - ASSERT(agbno != NULLAGBLOCK); |
|---|
| 720 | | - d = XFS_AGB_TO_DADDR(mp, agno, agbno); |
|---|
| 721 | | - return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); |
|---|
| 722 | | -} |
|---|
| 723 | | - |
|---|
| 724 | | -/* |
|---|
| 725 | | - * Check for the cursor referring to the last block at the given level. |
|---|
| 726 | | - */ |
|---|
| 727 | | -int /* 1=is last block, 0=not last block */ |
|---|
| 728 | | -xfs_btree_islastblock( |
|---|
| 729 | | - xfs_btree_cur_t *cur, /* btree cursor */ |
|---|
| 730 | | - int level) /* level to check */ |
|---|
| 731 | | -{ |
|---|
| 732 | | - struct xfs_btree_block *block; /* generic btree block pointer */ |
|---|
| 733 | | - xfs_buf_t *bp; /* buffer containing block */ |
|---|
| 734 | | - |
|---|
| 735 | | - block = xfs_btree_get_block(cur, level, &bp); |
|---|
| 736 | | - xfs_btree_check_block(cur, block, level, bp); |
|---|
| 737 | | - if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
|---|
| 738 | | - return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); |
|---|
| 739 | | - else |
|---|
| 740 | | - return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); |
|---|
| 741 | 689 | } |
|---|
| 742 | 690 | |
|---|
| 743 | 691 | /* |
|---|
| .. | .. |
|---|
| 845 | 793 | struct xfs_mount *mp, /* file system mount point */ |
|---|
| 846 | 794 | struct xfs_trans *tp, /* transaction pointer */ |
|---|
| 847 | 795 | xfs_fsblock_t fsbno, /* file system block number */ |
|---|
| 848 | | - uint lock, /* lock flags for read_buf */ |
|---|
| 849 | 796 | struct xfs_buf **bpp, /* buffer for fsbno */ |
|---|
| 850 | 797 | int refval, /* ref count value for buffer */ |
|---|
| 851 | 798 | const struct xfs_buf_ops *ops) |
|---|
| .. | .. |
|---|
| 858 | 805 | return -EFSCORRUPTED; |
|---|
| 859 | 806 | d = XFS_FSB_TO_DADDR(mp, fsbno); |
|---|
| 860 | 807 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, |
|---|
| 861 | | - mp->m_bsize, lock, &bp, ops); |
|---|
| 808 | + mp->m_bsize, 0, &bp, ops); |
|---|
| 862 | 809 | if (error) |
|---|
| 863 | 810 | return error; |
|---|
| 864 | 811 | if (bp) |
|---|
| .. | .. |
|---|
| 944 | 891 | |
|---|
| 945 | 892 | |
|---|
| 946 | 893 | if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { |
|---|
| 947 | | - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, |
|---|
| 894 | + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno, |
|---|
| 948 | 895 | left, 1, cur->bc_ops->buf_ops); |
|---|
| 949 | 896 | rval++; |
|---|
| 950 | 897 | } |
|---|
| 951 | 898 | |
|---|
| 952 | 899 | if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { |
|---|
| 953 | | - xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, |
|---|
| 900 | + xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno, |
|---|
| 954 | 901 | right, 1, cur->bc_ops->buf_ops); |
|---|
| 955 | 902 | rval++; |
|---|
| 956 | 903 | } |
|---|
| .. | .. |
|---|
| 1008 | 955 | *daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno); |
|---|
| 1009 | 956 | } else { |
|---|
| 1010 | 957 | agbno = be32_to_cpu(ptr->s); |
|---|
| 1011 | | - *daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, |
|---|
| 958 | + *daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_ag.agno, |
|---|
| 1012 | 959 | agbno); |
|---|
| 1013 | 960 | } |
|---|
| 1014 | 961 | |
|---|
| .. | .. |
|---|
| 1077 | 1024 | return ptr->s == cpu_to_be32(NULLAGBLOCK); |
|---|
| 1078 | 1025 | } |
|---|
| 1079 | 1026 | |
|---|
| 1080 | | -STATIC void |
|---|
| 1027 | +void |
|---|
| 1081 | 1028 | xfs_btree_set_ptr_null( |
|---|
| 1082 | 1029 | struct xfs_btree_cur *cur, |
|---|
| 1083 | 1030 | union xfs_btree_ptr *ptr) |
|---|
| .. | .. |
|---|
| 1113 | 1060 | } |
|---|
| 1114 | 1061 | } |
|---|
| 1115 | 1062 | |
|---|
| 1116 | | -STATIC void |
|---|
| 1063 | +void |
|---|
| 1117 | 1064 | xfs_btree_set_sibling( |
|---|
| 1118 | 1065 | struct xfs_btree_cur *cur, |
|---|
| 1119 | 1066 | struct xfs_btree_block *block, |
|---|
| .. | .. |
|---|
| 1185 | 1132 | xfs_btnum_t btnum, |
|---|
| 1186 | 1133 | __u16 level, |
|---|
| 1187 | 1134 | __u16 numrecs, |
|---|
| 1188 | | - __u64 owner, |
|---|
| 1189 | | - unsigned int flags) |
|---|
| 1135 | + __u64 owner) |
|---|
| 1190 | 1136 | { |
|---|
| 1191 | 1137 | xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, |
|---|
| 1192 | | - btnum, level, numrecs, owner, flags); |
|---|
| 1138 | + btnum, level, numrecs, owner, 0); |
|---|
| 1193 | 1139 | } |
|---|
| 1194 | 1140 | |
|---|
| 1195 | | -STATIC void |
|---|
| 1141 | +void |
|---|
| 1196 | 1142 | xfs_btree_init_block_cur( |
|---|
| 1197 | 1143 | struct xfs_btree_cur *cur, |
|---|
| 1198 | 1144 | struct xfs_buf *bp, |
|---|
| .. | .. |
|---|
| 1208 | 1154 | * code. |
|---|
| 1209 | 1155 | */ |
|---|
| 1210 | 1156 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
|---|
| 1211 | | - owner = cur->bc_private.b.ip->i_ino; |
|---|
| 1157 | + owner = cur->bc_ino.ip->i_ino; |
|---|
| 1212 | 1158 | else |
|---|
| 1213 | | - owner = cur->bc_private.a.agno; |
|---|
| 1159 | + owner = cur->bc_ag.agno; |
|---|
| 1214 | 1160 | |
|---|
| 1215 | 1161 | xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn, |
|---|
| 1216 | 1162 | cur->bc_btnum, level, numrecs, |
|---|
| .. | .. |
|---|
| 1284 | 1230 | } |
|---|
| 1285 | 1231 | } |
|---|
| 1286 | 1232 | |
|---|
| 1287 | | -STATIC int |
|---|
| 1233 | +int |
|---|
| 1288 | 1234 | xfs_btree_get_buf_block( |
|---|
| 1289 | 1235 | struct xfs_btree_cur *cur, |
|---|
| 1290 | 1236 | union xfs_btree_ptr *ptr, |
|---|
| 1291 | | - int flags, |
|---|
| 1292 | 1237 | struct xfs_btree_block **block, |
|---|
| 1293 | 1238 | struct xfs_buf **bpp) |
|---|
| 1294 | 1239 | { |
|---|
| .. | .. |
|---|
| 1296 | 1241 | xfs_daddr_t d; |
|---|
| 1297 | 1242 | int error; |
|---|
| 1298 | 1243 | |
|---|
| 1299 | | - /* need to sort out how callers deal with failures first */ |
|---|
| 1300 | | - ASSERT(!(flags & XBF_TRYLOCK)); |
|---|
| 1301 | | - |
|---|
| 1302 | 1244 | error = xfs_btree_ptr_to_daddr(cur, ptr, &d); |
|---|
| 1303 | 1245 | if (error) |
|---|
| 1304 | 1246 | return error; |
|---|
| 1305 | | - *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, |
|---|
| 1306 | | - mp->m_bsize, flags); |
|---|
| 1307 | | - |
|---|
| 1308 | | - if (!*bpp) |
|---|
| 1309 | | - return -ENOMEM; |
|---|
| 1247 | + error = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, |
|---|
| 1248 | + 0, bpp); |
|---|
| 1249 | + if (error) |
|---|
| 1250 | + return error; |
|---|
| 1310 | 1251 | |
|---|
| 1311 | 1252 | (*bpp)->b_ops = cur->bc_ops->buf_ops; |
|---|
| 1312 | 1253 | *block = XFS_BUF_TO_BLOCK(*bpp); |
|---|
| .. | .. |
|---|
| 1349 | 1290 | /* |
|---|
| 1350 | 1291 | * Copy keys from one btree block to another. |
|---|
| 1351 | 1292 | */ |
|---|
| 1352 | | -STATIC void |
|---|
| 1293 | +void |
|---|
| 1353 | 1294 | xfs_btree_copy_keys( |
|---|
| 1354 | 1295 | struct xfs_btree_cur *cur, |
|---|
| 1355 | 1296 | union xfs_btree_key *dst_key, |
|---|
| .. | .. |
|---|
| 1377 | 1318 | /* |
|---|
| 1378 | 1319 | * Copy block pointers from one btree block to another. |
|---|
| 1379 | 1320 | */ |
|---|
| 1380 | | -STATIC void |
|---|
| 1321 | +void |
|---|
| 1381 | 1322 | xfs_btree_copy_ptrs( |
|---|
| 1382 | 1323 | struct xfs_btree_cur *cur, |
|---|
| 1383 | 1324 | union xfs_btree_ptr *dst_ptr, |
|---|
| 1384 | | - union xfs_btree_ptr *src_ptr, |
|---|
| 1325 | + const union xfs_btree_ptr *src_ptr, |
|---|
| 1385 | 1326 | int numptrs) |
|---|
| 1386 | 1327 | { |
|---|
| 1387 | 1328 | ASSERT(numptrs >= 0); |
|---|
| .. | .. |
|---|
| 1462 | 1403 | xfs_btree_key_offset(cur, first), |
|---|
| 1463 | 1404 | xfs_btree_key_offset(cur, last + 1) - 1); |
|---|
| 1464 | 1405 | } else { |
|---|
| 1465 | | - xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, |
|---|
| 1466 | | - xfs_ilog_fbroot(cur->bc_private.b.whichfork)); |
|---|
| 1406 | + xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, |
|---|
| 1407 | + xfs_ilog_fbroot(cur->bc_ino.whichfork)); |
|---|
| 1467 | 1408 | } |
|---|
| 1468 | 1409 | } |
|---|
| 1469 | 1410 | |
|---|
| .. | .. |
|---|
| 1505 | 1446 | xfs_btree_ptr_offset(cur, first, level), |
|---|
| 1506 | 1447 | xfs_btree_ptr_offset(cur, last + 1, level) - 1); |
|---|
| 1507 | 1448 | } else { |
|---|
| 1508 | | - xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, |
|---|
| 1509 | | - xfs_ilog_fbroot(cur->bc_private.b.whichfork)); |
|---|
| 1449 | + xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, |
|---|
| 1450 | + xfs_ilog_fbroot(cur->bc_ino.whichfork)); |
|---|
| 1510 | 1451 | } |
|---|
| 1511 | 1452 | |
|---|
| 1512 | 1453 | } |
|---|
| .. | .. |
|---|
| 1574 | 1515 | xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF); |
|---|
| 1575 | 1516 | xfs_trans_log_buf(cur->bc_tp, bp, first, last); |
|---|
| 1576 | 1517 | } else { |
|---|
| 1577 | | - xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, |
|---|
| 1578 | | - xfs_ilog_fbroot(cur->bc_private.b.whichfork)); |
|---|
| 1518 | + xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, |
|---|
| 1519 | + xfs_ilog_fbroot(cur->bc_ino.whichfork)); |
|---|
| 1579 | 1520 | } |
|---|
| 1580 | 1521 | } |
|---|
| 1581 | 1522 | |
|---|
| .. | .. |
|---|
| 1812 | 1753 | |
|---|
| 1813 | 1754 | /* Check the inode owner since the verifiers don't. */ |
|---|
| 1814 | 1755 | if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) && |
|---|
| 1815 | | - !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_INVALID_OWNER) && |
|---|
| 1756 | + !(cur->bc_ino.flags & XFS_BTCUR_BMBT_INVALID_OWNER) && |
|---|
| 1816 | 1757 | (cur->bc_flags & XFS_BTREE_LONG_PTRS) && |
|---|
| 1817 | 1758 | be64_to_cpu((*blkp)->bb_u.l.bb_owner) != |
|---|
| 1818 | | - cur->bc_private.b.ip->i_ino) |
|---|
| 1759 | + cur->bc_ino.ip->i_ino) |
|---|
| 1819 | 1760 | goto out_bad; |
|---|
| 1820 | 1761 | |
|---|
| 1821 | 1762 | /* Did we get the level we were looking for? */ |
|---|
| .. | .. |
|---|
| 1831 | 1772 | |
|---|
| 1832 | 1773 | out_bad: |
|---|
| 1833 | 1774 | *blkp = NULL; |
|---|
| 1775 | + xfs_buf_mark_corrupt(bp); |
|---|
| 1834 | 1776 | xfs_trans_brelse(cur->bc_tp, bp); |
|---|
| 1835 | 1777 | return -EFSCORRUPTED; |
|---|
| 1836 | 1778 | } |
|---|
| .. | .. |
|---|
| 1878 | 1820 | XFS_BTREE_STATS_INC(cur, lookup); |
|---|
| 1879 | 1821 | |
|---|
| 1880 | 1822 | /* No such thing as a zero-level tree. */ |
|---|
| 1881 | | - if (cur->bc_nlevels == 0) |
|---|
| 1823 | + if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0)) |
|---|
| 1882 | 1824 | return -EFSCORRUPTED; |
|---|
| 1883 | 1825 | |
|---|
| 1884 | 1826 | block = NULL; |
|---|
| .. | .. |
|---|
| 1998 | 1940 | error = xfs_btree_increment(cur, 0, &i); |
|---|
| 1999 | 1941 | if (error) |
|---|
| 2000 | 1942 | goto error0; |
|---|
| 2001 | | - XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
|---|
| 1943 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) |
|---|
| 1944 | + return -EFSCORRUPTED; |
|---|
| 2002 | 1945 | *stat = 1; |
|---|
| 2003 | 1946 | return 0; |
|---|
| 2004 | 1947 | } |
|---|
| .. | .. |
|---|
| 2419 | 2362 | XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1); |
|---|
| 2420 | 2363 | if (level > 0) { |
|---|
| 2421 | 2364 | /* It's a nonleaf. operate on keys and ptrs */ |
|---|
| 2422 | | - int i; /* loop index */ |
|---|
| 2423 | | - |
|---|
| 2424 | 2365 | for (i = 0; i < rrecs; i++) { |
|---|
| 2425 | 2366 | error = xfs_btree_debug_check_ptr(cur, rpp, i + 1, level); |
|---|
| 2426 | 2367 | if (error) |
|---|
| .. | .. |
|---|
| 2453 | 2394 | if (error) |
|---|
| 2454 | 2395 | goto error0; |
|---|
| 2455 | 2396 | i = xfs_btree_firstrec(tcur, level); |
|---|
| 2456 | | - XFS_WANT_CORRUPTED_GOTO(tcur->bc_mp, i == 1, error0); |
|---|
| 2397 | + if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) { |
|---|
| 2398 | + error = -EFSCORRUPTED; |
|---|
| 2399 | + goto error0; |
|---|
| 2400 | + } |
|---|
| 2457 | 2401 | |
|---|
| 2458 | 2402 | error = xfs_btree_decrement(tcur, level, &i); |
|---|
| 2459 | 2403 | if (error) |
|---|
| .. | .. |
|---|
| 2620 | 2564 | if (error) |
|---|
| 2621 | 2565 | goto error0; |
|---|
| 2622 | 2566 | i = xfs_btree_lastrec(tcur, level); |
|---|
| 2623 | | - XFS_WANT_CORRUPTED_GOTO(tcur->bc_mp, i == 1, error0); |
|---|
| 2567 | + if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) { |
|---|
| 2568 | + error = -EFSCORRUPTED; |
|---|
| 2569 | + goto error0; |
|---|
| 2570 | + } |
|---|
| 2624 | 2571 | |
|---|
| 2625 | 2572 | error = xfs_btree_increment(tcur, level, &i); |
|---|
| 2626 | 2573 | if (error) |
|---|
| .. | .. |
|---|
| 2706 | 2653 | XFS_BTREE_STATS_INC(cur, alloc); |
|---|
| 2707 | 2654 | |
|---|
| 2708 | 2655 | /* Set up the new block as "right". */ |
|---|
| 2709 | | - error = xfs_btree_get_buf_block(cur, &rptr, 0, &right, &rbp); |
|---|
| 2656 | + error = xfs_btree_get_buf_block(cur, &rptr, &right, &rbp); |
|---|
| 2710 | 2657 | if (error) |
|---|
| 2711 | 2658 | goto error0; |
|---|
| 2712 | 2659 | |
|---|
| .. | .. |
|---|
| 2864 | 2811 | struct xfs_btree_split_args *args = container_of(work, |
|---|
| 2865 | 2812 | struct xfs_btree_split_args, work); |
|---|
| 2866 | 2813 | unsigned long pflags; |
|---|
| 2867 | | - unsigned long new_pflags = PF_MEMALLOC_NOFS; |
|---|
| 2814 | + unsigned long new_pflags = 0; |
|---|
| 2868 | 2815 | |
|---|
| 2869 | 2816 | /* |
|---|
| 2870 | 2817 | * we are in a transaction context here, but may also be doing work |
|---|
| .. | .. |
|---|
| 2876 | 2823 | new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; |
|---|
| 2877 | 2824 | |
|---|
| 2878 | 2825 | current_set_flags_nested(&pflags, new_pflags); |
|---|
| 2826 | + xfs_trans_set_context(args->cur->bc_tp); |
|---|
| 2879 | 2827 | |
|---|
| 2880 | 2828 | args->result = __xfs_btree_split(args->cur, args->level, args->ptrp, |
|---|
| 2881 | 2829 | args->key, args->curp, args->stat); |
|---|
| 2830 | + |
|---|
| 2831 | + xfs_trans_clear_context(args->cur->bc_tp); |
|---|
| 2832 | + current_restore_flags_nested(&pflags, new_pflags); |
|---|
| 2833 | + |
|---|
| 2834 | + /* |
|---|
| 2835 | + * Do not access args after complete() has run here. We don't own args |
|---|
| 2836 | + * and the owner may run and free args before we return here. |
|---|
| 2837 | + */ |
|---|
| 2882 | 2838 | complete(args->done); |
|---|
| 2883 | 2839 | |
|---|
| 2884 | | - current_restore_flags_nested(&pflags, new_pflags); |
|---|
| 2885 | 2840 | } |
|---|
| 2886 | 2841 | |
|---|
| 2887 | 2842 | /* |
|---|
| .. | .. |
|---|
| 2961 | 2916 | XFS_BTREE_STATS_INC(cur, alloc); |
|---|
| 2962 | 2917 | |
|---|
| 2963 | 2918 | /* Copy the root into a real block. */ |
|---|
| 2964 | | - error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp); |
|---|
| 2919 | + error = xfs_btree_get_buf_block(cur, &nptr, &cblock, &cbp); |
|---|
| 2965 | 2920 | if (error) |
|---|
| 2966 | 2921 | goto error0; |
|---|
| 2967 | 2922 | |
|---|
| .. | .. |
|---|
| 3001 | 2956 | |
|---|
| 3002 | 2957 | xfs_btree_copy_ptrs(cur, pp, &nptr, 1); |
|---|
| 3003 | 2958 | |
|---|
| 3004 | | - xfs_iroot_realloc(cur->bc_private.b.ip, |
|---|
| 2959 | + xfs_iroot_realloc(cur->bc_ino.ip, |
|---|
| 3005 | 2960 | 1 - xfs_btree_get_numrecs(cblock), |
|---|
| 3006 | | - cur->bc_private.b.whichfork); |
|---|
| 2961 | + cur->bc_ino.whichfork); |
|---|
| 3007 | 2962 | |
|---|
| 3008 | 2963 | xfs_btree_setbuf(cur, level, cbp); |
|---|
| 3009 | 2964 | |
|---|
| .. | .. |
|---|
| 3016 | 2971 | xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); |
|---|
| 3017 | 2972 | |
|---|
| 3018 | 2973 | *logflags |= |
|---|
| 3019 | | - XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork); |
|---|
| 2974 | + XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork); |
|---|
| 3020 | 2975 | *stat = 1; |
|---|
| 3021 | 2976 | return 0; |
|---|
| 3022 | 2977 | error0: |
|---|
| .. | .. |
|---|
| 3058 | 3013 | XFS_BTREE_STATS_INC(cur, alloc); |
|---|
| 3059 | 3014 | |
|---|
| 3060 | 3015 | /* Set up the new block. */ |
|---|
| 3061 | | - error = xfs_btree_get_buf_block(cur, &lptr, 0, &new, &nbp); |
|---|
| 3016 | + error = xfs_btree_get_buf_block(cur, &lptr, &new, &nbp); |
|---|
| 3062 | 3017 | if (error) |
|---|
| 3063 | 3018 | goto error0; |
|---|
| 3064 | 3019 | |
|---|
| .. | .. |
|---|
| 3168 | 3123 | |
|---|
| 3169 | 3124 | if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) && |
|---|
| 3170 | 3125 | level == cur->bc_nlevels - 1) { |
|---|
| 3171 | | - struct xfs_inode *ip = cur->bc_private.b.ip; |
|---|
| 3126 | + struct xfs_inode *ip = cur->bc_ino.ip; |
|---|
| 3172 | 3127 | |
|---|
| 3173 | 3128 | if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) { |
|---|
| 3174 | 3129 | /* A root block that can be made bigger. */ |
|---|
| 3175 | | - xfs_iroot_realloc(ip, 1, cur->bc_private.b.whichfork); |
|---|
| 3130 | + xfs_iroot_realloc(ip, 1, cur->bc_ino.whichfork); |
|---|
| 3176 | 3131 | *stat = 1; |
|---|
| 3177 | 3132 | } else { |
|---|
| 3178 | 3133 | /* A root block that needs replacing */ |
|---|
| .. | .. |
|---|
| 3235 | 3190 | struct xfs_btree_block *block; /* btree block */ |
|---|
| 3236 | 3191 | struct xfs_buf *bp; /* buffer for block */ |
|---|
| 3237 | 3192 | union xfs_btree_ptr nptr; /* new block ptr */ |
|---|
| 3238 | | - struct xfs_btree_cur *ncur; /* new btree cursor */ |
|---|
| 3193 | + struct xfs_btree_cur *ncur = NULL; /* new btree cursor */ |
|---|
| 3239 | 3194 | union xfs_btree_key nkey; /* new block key */ |
|---|
| 3240 | 3195 | union xfs_btree_key *lkey; |
|---|
| 3241 | 3196 | int optr; /* old key/record index */ |
|---|
| .. | .. |
|---|
| 3315 | 3270 | #ifdef DEBUG |
|---|
| 3316 | 3271 | error = xfs_btree_check_block(cur, block, level, bp); |
|---|
| 3317 | 3272 | if (error) |
|---|
| 3318 | | - return error; |
|---|
| 3273 | + goto error0; |
|---|
| 3319 | 3274 | #endif |
|---|
| 3320 | 3275 | |
|---|
| 3321 | 3276 | /* |
|---|
| .. | .. |
|---|
| 3335 | 3290 | for (i = numrecs - ptr; i >= 0; i--) { |
|---|
| 3336 | 3291 | error = xfs_btree_debug_check_ptr(cur, pp, i, level); |
|---|
| 3337 | 3292 | if (error) |
|---|
| 3338 | | - return error; |
|---|
| 3293 | + goto error0; |
|---|
| 3339 | 3294 | } |
|---|
| 3340 | 3295 | |
|---|
| 3341 | 3296 | xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1); |
|---|
| .. | .. |
|---|
| 3420 | 3375 | return 0; |
|---|
| 3421 | 3376 | |
|---|
| 3422 | 3377 | error0: |
|---|
| 3378 | + if (ncur) |
|---|
| 3379 | + xfs_btree_del_cursor(ncur, error); |
|---|
| 3423 | 3380 | return error; |
|---|
| 3424 | 3381 | } |
|---|
| 3425 | 3382 | |
|---|
| .. | .. |
|---|
| 3474 | 3431 | goto error0; |
|---|
| 3475 | 3432 | } |
|---|
| 3476 | 3433 | |
|---|
| 3477 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3434 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3435 | + error = -EFSCORRUPTED; |
|---|
| 3436 | + goto error0; |
|---|
| 3437 | + } |
|---|
| 3478 | 3438 | level++; |
|---|
| 3479 | 3439 | |
|---|
| 3480 | 3440 | /* |
|---|
| .. | .. |
|---|
| 3515 | 3475 | xfs_btree_kill_iroot( |
|---|
| 3516 | 3476 | struct xfs_btree_cur *cur) |
|---|
| 3517 | 3477 | { |
|---|
| 3518 | | - int whichfork = cur->bc_private.b.whichfork; |
|---|
| 3519 | | - struct xfs_inode *ip = cur->bc_private.b.ip; |
|---|
| 3478 | + int whichfork = cur->bc_ino.whichfork; |
|---|
| 3479 | + struct xfs_inode *ip = cur->bc_ino.ip; |
|---|
| 3520 | 3480 | struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); |
|---|
| 3521 | 3481 | struct xfs_btree_block *block; |
|---|
| 3522 | 3482 | struct xfs_btree_block *cblock; |
|---|
| .. | .. |
|---|
| 3574 | 3534 | |
|---|
| 3575 | 3535 | index = numrecs - cur->bc_ops->get_maxrecs(cur, level); |
|---|
| 3576 | 3536 | if (index) { |
|---|
| 3577 | | - xfs_iroot_realloc(cur->bc_private.b.ip, index, |
|---|
| 3578 | | - cur->bc_private.b.whichfork); |
|---|
| 3537 | + xfs_iroot_realloc(cur->bc_ino.ip, index, |
|---|
| 3538 | + cur->bc_ino.whichfork); |
|---|
| 3579 | 3539 | block = ifp->if_broot; |
|---|
| 3580 | 3540 | } |
|---|
| 3581 | 3541 | |
|---|
| .. | .. |
|---|
| 3604 | 3564 | cur->bc_bufs[level - 1] = NULL; |
|---|
| 3605 | 3565 | be16_add_cpu(&block->bb_level, -1); |
|---|
| 3606 | 3566 | xfs_trans_log_inode(cur->bc_tp, ip, |
|---|
| 3607 | | - XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork)); |
|---|
| 3567 | + XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork)); |
|---|
| 3608 | 3568 | cur->bc_nlevels--; |
|---|
| 3609 | 3569 | out0: |
|---|
| 3610 | 3570 | return 0; |
|---|
| .. | .. |
|---|
| 3772 | 3732 | */ |
|---|
| 3773 | 3733 | if (level == cur->bc_nlevels - 1) { |
|---|
| 3774 | 3734 | if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) { |
|---|
| 3775 | | - xfs_iroot_realloc(cur->bc_private.b.ip, -1, |
|---|
| 3776 | | - cur->bc_private.b.whichfork); |
|---|
| 3735 | + xfs_iroot_realloc(cur->bc_ino.ip, -1, |
|---|
| 3736 | + cur->bc_ino.whichfork); |
|---|
| 3777 | 3737 | |
|---|
| 3778 | 3738 | error = xfs_btree_kill_iroot(cur); |
|---|
| 3779 | 3739 | if (error) |
|---|
| .. | .. |
|---|
| 3878 | 3838 | * Actually any entry but the first would suffice. |
|---|
| 3879 | 3839 | */ |
|---|
| 3880 | 3840 | i = xfs_btree_lastrec(tcur, level); |
|---|
| 3881 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3841 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3842 | + error = -EFSCORRUPTED; |
|---|
| 3843 | + goto error0; |
|---|
| 3844 | + } |
|---|
| 3882 | 3845 | |
|---|
| 3883 | 3846 | error = xfs_btree_increment(tcur, level, &i); |
|---|
| 3884 | 3847 | if (error) |
|---|
| 3885 | 3848 | goto error0; |
|---|
| 3886 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3849 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3850 | + error = -EFSCORRUPTED; |
|---|
| 3851 | + goto error0; |
|---|
| 3852 | + } |
|---|
| 3887 | 3853 | |
|---|
| 3888 | 3854 | i = xfs_btree_lastrec(tcur, level); |
|---|
| 3889 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3855 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3856 | + error = -EFSCORRUPTED; |
|---|
| 3857 | + goto error0; |
|---|
| 3858 | + } |
|---|
| 3890 | 3859 | |
|---|
| 3891 | 3860 | /* Grab a pointer to the block. */ |
|---|
| 3892 | 3861 | right = xfs_btree_get_block(tcur, level, &rbp); |
|---|
| .. | .. |
|---|
| 3930 | 3899 | rrecs = xfs_btree_get_numrecs(right); |
|---|
| 3931 | 3900 | if (!xfs_btree_ptr_is_null(cur, &lptr)) { |
|---|
| 3932 | 3901 | i = xfs_btree_firstrec(tcur, level); |
|---|
| 3933 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3902 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3903 | + error = -EFSCORRUPTED; |
|---|
| 3904 | + goto error0; |
|---|
| 3905 | + } |
|---|
| 3934 | 3906 | |
|---|
| 3935 | 3907 | error = xfs_btree_decrement(tcur, level, &i); |
|---|
| 3936 | 3908 | if (error) |
|---|
| 3937 | 3909 | goto error0; |
|---|
| 3938 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3910 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3911 | + error = -EFSCORRUPTED; |
|---|
| 3912 | + goto error0; |
|---|
| 3913 | + } |
|---|
| 3939 | 3914 | } |
|---|
| 3940 | 3915 | } |
|---|
| 3941 | 3916 | |
|---|
| .. | .. |
|---|
| 3949 | 3924 | * previous block. |
|---|
| 3950 | 3925 | */ |
|---|
| 3951 | 3926 | i = xfs_btree_firstrec(tcur, level); |
|---|
| 3952 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3927 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3928 | + error = -EFSCORRUPTED; |
|---|
| 3929 | + goto error0; |
|---|
| 3930 | + } |
|---|
| 3953 | 3931 | |
|---|
| 3954 | 3932 | error = xfs_btree_decrement(tcur, level, &i); |
|---|
| 3955 | 3933 | if (error) |
|---|
| 3956 | 3934 | goto error0; |
|---|
| 3957 | 3935 | i = xfs_btree_firstrec(tcur, level); |
|---|
| 3958 | | - XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
|---|
| 3936 | + if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) { |
|---|
| 3937 | + error = -EFSCORRUPTED; |
|---|
| 3938 | + goto error0; |
|---|
| 3939 | + } |
|---|
| 3959 | 3940 | |
|---|
| 3960 | 3941 | /* Grab a pointer to the block. */ |
|---|
| 3961 | 3942 | left = xfs_btree_get_block(tcur, level, &lbp); |
|---|
| .. | .. |
|---|
| 4297 | 4278 | xfs_btree_visit_blocks( |
|---|
| 4298 | 4279 | struct xfs_btree_cur *cur, |
|---|
| 4299 | 4280 | xfs_btree_visit_blocks_fn fn, |
|---|
| 4281 | + unsigned int flags, |
|---|
| 4300 | 4282 | void *data) |
|---|
| 4301 | 4283 | { |
|---|
| 4302 | 4284 | union xfs_btree_ptr lptr; |
|---|
| .. | .. |
|---|
| 4322 | 4304 | |
|---|
| 4323 | 4305 | /* save for the next iteration of the loop */ |
|---|
| 4324 | 4306 | xfs_btree_copy_ptrs(cur, &lptr, ptr, 1); |
|---|
| 4307 | + |
|---|
| 4308 | + if (!(flags & XFS_BTREE_VISIT_LEAVES)) |
|---|
| 4309 | + continue; |
|---|
| 4310 | + } else if (!(flags & XFS_BTREE_VISIT_RECORDS)) { |
|---|
| 4311 | + continue; |
|---|
| 4325 | 4312 | } |
|---|
| 4326 | 4313 | |
|---|
| 4327 | 4314 | /* for each buffer in the level */ |
|---|
| .. | .. |
|---|
| 4424 | 4411 | bbcoi.buffer_list = buffer_list; |
|---|
| 4425 | 4412 | |
|---|
| 4426 | 4413 | return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner, |
|---|
| 4427 | | - &bbcoi); |
|---|
| 4414 | + XFS_BTREE_VISIT_ALL, &bbcoi); |
|---|
| 4428 | 4415 | } |
|---|
| 4429 | 4416 | |
|---|
| 4430 | 4417 | /* Verify the v5 fields of a long-format btree block. */ |
|---|
| .. | .. |
|---|
| 4433 | 4420 | struct xfs_buf *bp, |
|---|
| 4434 | 4421 | uint64_t owner) |
|---|
| 4435 | 4422 | { |
|---|
| 4436 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 4423 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 4437 | 4424 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 4438 | 4425 | |
|---|
| 4439 | 4426 | if (!xfs_sb_version_hascrc(&mp->m_sb)) |
|---|
| .. | .. |
|---|
| 4454 | 4441 | struct xfs_buf *bp, |
|---|
| 4455 | 4442 | unsigned int max_recs) |
|---|
| 4456 | 4443 | { |
|---|
| 4457 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 4444 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 4458 | 4445 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 4459 | 4446 | |
|---|
| 4460 | 4447 | /* numrecs verification */ |
|---|
| .. | .. |
|---|
| 4477 | 4464 | * btree block |
|---|
| 4478 | 4465 | * |
|---|
| 4479 | 4466 | * @bp: buffer containing the btree block |
|---|
| 4480 | | - * @max_recs: pointer to the m_*_mxr max records field in the xfs mount |
|---|
| 4481 | | - * @pag_max_level: pointer to the per-ag max level field |
|---|
| 4482 | 4467 | */ |
|---|
| 4483 | 4468 | xfs_failaddr_t |
|---|
| 4484 | 4469 | xfs_btree_sblock_v5hdr_verify( |
|---|
| 4485 | 4470 | struct xfs_buf *bp) |
|---|
| 4486 | 4471 | { |
|---|
| 4487 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 4472 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 4488 | 4473 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 4489 | 4474 | struct xfs_perag *pag = bp->b_pag; |
|---|
| 4490 | 4475 | |
|---|
| .. | .. |
|---|
| 4510 | 4495 | struct xfs_buf *bp, |
|---|
| 4511 | 4496 | unsigned int max_recs) |
|---|
| 4512 | 4497 | { |
|---|
| 4513 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
|---|
| 4498 | + struct xfs_mount *mp = bp->b_mount; |
|---|
| 4514 | 4499 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
|---|
| 4515 | 4500 | xfs_agblock_t agno; |
|---|
| 4516 | 4501 | |
|---|
| .. | .. |
|---|
| 4611 | 4596 | |
|---|
| 4612 | 4597 | /* Callback */ |
|---|
| 4613 | 4598 | error = fn(cur, recp, priv); |
|---|
| 4614 | | - if (error < 0 || error == XFS_BTREE_QUERY_RANGE_ABORT) |
|---|
| 4599 | + if (error) |
|---|
| 4615 | 4600 | break; |
|---|
| 4616 | 4601 | |
|---|
| 4617 | 4602 | advloop: |
|---|
| .. | .. |
|---|
| 4713 | 4698 | */ |
|---|
| 4714 | 4699 | if (ldiff >= 0 && hdiff >= 0) { |
|---|
| 4715 | 4700 | error = fn(cur, recp, priv); |
|---|
| 4716 | | - if (error < 0 || |
|---|
| 4717 | | - error == XFS_BTREE_QUERY_RANGE_ABORT) |
|---|
| 4701 | + if (error) |
|---|
| 4718 | 4702 | break; |
|---|
| 4719 | 4703 | } else if (hdiff < 0) { |
|---|
| 4720 | 4704 | /* Record is larger than high key; pop. */ |
|---|
| .. | .. |
|---|
| 4785 | 4769 | * Query a btree for all records overlapping a given interval of keys. The |
|---|
| 4786 | 4770 | * supplied function will be called with each record found; return one of the |
|---|
| 4787 | 4771 | * XFS_BTREE_QUERY_RANGE_{CONTINUE,ABORT} values or the usual negative error |
|---|
| 4788 | | - * code. This function returns XFS_BTREE_QUERY_RANGE_ABORT, zero, or a |
|---|
| 4789 | | - * negative error code. |
|---|
| 4772 | + * code. This function returns -ECANCELED, zero, or a negative error code. |
|---|
| 4790 | 4773 | */ |
|---|
| 4791 | 4774 | int |
|---|
| 4792 | 4775 | xfs_btree_query_range( |
|---|
| .. | .. |
|---|
| 4880 | 4863 | { |
|---|
| 4881 | 4864 | *blocks = 0; |
|---|
| 4882 | 4865 | return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper, |
|---|
| 4883 | | - blocks); |
|---|
| 4866 | + XFS_BTREE_VISIT_ALL, blocks); |
|---|
| 4884 | 4867 | } |
|---|
| 4885 | 4868 | |
|---|
| 4886 | 4869 | /* Compare two btree pointers. */ |
|---|
| .. | .. |
|---|
| 4902 | 4885 | union xfs_btree_rec *rec, |
|---|
| 4903 | 4886 | void *priv) |
|---|
| 4904 | 4887 | { |
|---|
| 4905 | | - return XFS_BTREE_QUERY_RANGE_ABORT; |
|---|
| 4888 | + return -ECANCELED; |
|---|
| 4906 | 4889 | } |
|---|
| 4907 | 4890 | |
|---|
| 4908 | 4891 | /* Is there a record covering a given range of keys? */ |
|---|
| .. | .. |
|---|
| 4917 | 4900 | |
|---|
| 4918 | 4901 | error = xfs_btree_query_range(cur, low, high, |
|---|
| 4919 | 4902 | &xfs_btree_has_record_helper, NULL); |
|---|
| 4920 | | - if (error == XFS_BTREE_QUERY_RANGE_ABORT) { |
|---|
| 4903 | + if (error == -ECANCELED) { |
|---|
| 4921 | 4904 | *exists = true; |
|---|
| 4922 | 4905 | return 0; |
|---|
| 4923 | 4906 | } |
|---|