hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/fs/xfs/libxfs/xfs_btree.c
....@@ -11,18 +11,16 @@
1111 #include "xfs_trans_resv.h"
1212 #include "xfs_bit.h"
1313 #include "xfs_mount.h"
14
-#include "xfs_defer.h"
1514 #include "xfs_inode.h"
1615 #include "xfs_trans.h"
17
-#include "xfs_inode_item.h"
1816 #include "xfs_buf_item.h"
1917 #include "xfs_btree.h"
2018 #include "xfs_errortag.h"
2119 #include "xfs_error.h"
2220 #include "xfs_trace.h"
23
-#include "xfs_cksum.h"
2421 #include "xfs_alloc.h"
2522 #include "xfs_log.h"
23
+#include "xfs_btree_staging.h"
2624
2725 /*
2826 * Cursor allocation zone.
....@@ -108,11 +106,10 @@
108106 xfs_failaddr_t fa;
109107
110108 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)) {
113111 if (bp)
114112 trace_xfs_btree_corrupt(bp, _RET_IP_);
115
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
116113 return -EFSCORRUPTED;
117114 }
118115 return 0;
....@@ -172,11 +169,10 @@
172169 xfs_failaddr_t fa;
173170
174171 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)) {
177174 if (bp)
178175 trace_xfs_btree_corrupt(bp, _RET_IP_);
179
- XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
180176 return -EFSCORRUPTED;
181177 }
182178 return 0;
....@@ -219,7 +215,7 @@
219215 {
220216 if (level <= 0)
221217 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);
223219 }
224220
225221 /*
....@@ -239,8 +235,8 @@
239235 return 0;
240236 xfs_err(cur->bc_mp,
241237 "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,
244240 level, index);
245241 } else {
246242 if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]),
....@@ -248,7 +244,7 @@
248244 return 0;
249245 xfs_err(cur->bc_mp,
250246 "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,
252248 level, index);
253249 }
254250
....@@ -276,7 +272,7 @@
276272 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
277273 struct xfs_buf_log_item *bip = bp->b_log_item;
278274
279
- if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
275
+ if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb))
280276 return;
281277 if (bip)
282278 block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
....@@ -288,7 +284,7 @@
288284 struct xfs_buf *bp)
289285 {
290286 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;
292288
293289 if (xfs_sb_version_hascrc(&mp->m_sb)) {
294290 if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn)))
....@@ -314,7 +310,7 @@
314310 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
315311 struct xfs_buf_log_item *bip = bp->b_log_item;
316312
317
- if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
313
+ if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb))
318314 return;
319315 if (bip)
320316 block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
....@@ -326,7 +322,7 @@
326322 struct xfs_buf *bp)
327323 {
328324 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;
330326
331327 if (xfs_sb_version_hascrc(&mp->m_sb)) {
332328 if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
....@@ -357,20 +353,17 @@
357353 */
358354 void
359355 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 */
362358 {
363
- int i; /* btree level */
359
+ int i; /* btree level */
364360
365361 /*
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.
374367 */
375368 for (i = 0; i < cur->bc_nlevels; i++) {
376369 if (cur->bc_bufs[i])
....@@ -378,16 +371,18 @@
378371 else if (!error)
379372 break;
380373 }
374
+
381375 /*
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.
384380 */
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);
391386 }
392387
393388 /*
....@@ -647,6 +642,17 @@
647642 ((char *)block + xfs_btree_ptr_offset(cur, n, level));
648643 }
649644
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
+
650656 /*
651657 * Get the root block which is stored in the inode.
652658 *
....@@ -657,9 +663,8 @@
657663 xfs_btree_get_iroot(
658664 struct xfs_btree_cur *cur)
659665 {
660
- struct xfs_ifork *ifp;
666
+ struct xfs_ifork *ifp = xfs_btree_ifork_ptr(cur);
661667
662
- ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
663668 return (struct xfs_btree_block *)ifp->if_broot;
664669 }
665670
....@@ -681,63 +686,6 @@
681686
682687 *bpp = cur->bc_bufs[level];
683688 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);
741689 }
742690
743691 /*
....@@ -845,7 +793,6 @@
845793 struct xfs_mount *mp, /* file system mount point */
846794 struct xfs_trans *tp, /* transaction pointer */
847795 xfs_fsblock_t fsbno, /* file system block number */
848
- uint lock, /* lock flags for read_buf */
849796 struct xfs_buf **bpp, /* buffer for fsbno */
850797 int refval, /* ref count value for buffer */
851798 const struct xfs_buf_ops *ops)
....@@ -858,7 +805,7 @@
858805 return -EFSCORRUPTED;
859806 d = XFS_FSB_TO_DADDR(mp, fsbno);
860807 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);
862809 if (error)
863810 return error;
864811 if (bp)
....@@ -944,13 +891,13 @@
944891
945892
946893 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,
948895 left, 1, cur->bc_ops->buf_ops);
949896 rval++;
950897 }
951898
952899 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,
954901 right, 1, cur->bc_ops->buf_ops);
955902 rval++;
956903 }
....@@ -1008,7 +955,7 @@
1008955 *daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);
1009956 } else {
1010957 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,
1012959 agbno);
1013960 }
1014961
....@@ -1077,7 +1024,7 @@
10771024 return ptr->s == cpu_to_be32(NULLAGBLOCK);
10781025 }
10791026
1080
-STATIC void
1027
+void
10811028 xfs_btree_set_ptr_null(
10821029 struct xfs_btree_cur *cur,
10831030 union xfs_btree_ptr *ptr)
....@@ -1113,7 +1060,7 @@
11131060 }
11141061 }
11151062
1116
-STATIC void
1063
+void
11171064 xfs_btree_set_sibling(
11181065 struct xfs_btree_cur *cur,
11191066 struct xfs_btree_block *block,
....@@ -1185,14 +1132,13 @@
11851132 xfs_btnum_t btnum,
11861133 __u16 level,
11871134 __u16 numrecs,
1188
- __u64 owner,
1189
- unsigned int flags)
1135
+ __u64 owner)
11901136 {
11911137 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);
11931139 }
11941140
1195
-STATIC void
1141
+void
11961142 xfs_btree_init_block_cur(
11971143 struct xfs_btree_cur *cur,
11981144 struct xfs_buf *bp,
....@@ -1208,9 +1154,9 @@
12081154 * code.
12091155 */
12101156 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;
12121158 else
1213
- owner = cur->bc_private.a.agno;
1159
+ owner = cur->bc_ag.agno;
12141160
12151161 xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
12161162 cur->bc_btnum, level, numrecs,
....@@ -1284,11 +1230,10 @@
12841230 }
12851231 }
12861232
1287
-STATIC int
1233
+int
12881234 xfs_btree_get_buf_block(
12891235 struct xfs_btree_cur *cur,
12901236 union xfs_btree_ptr *ptr,
1291
- int flags,
12921237 struct xfs_btree_block **block,
12931238 struct xfs_buf **bpp)
12941239 {
....@@ -1296,17 +1241,13 @@
12961241 xfs_daddr_t d;
12971242 int error;
12981243
1299
- /* need to sort out how callers deal with failures first */
1300
- ASSERT(!(flags & XBF_TRYLOCK));
1301
-
13021244 error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
13031245 if (error)
13041246 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;
13101251
13111252 (*bpp)->b_ops = cur->bc_ops->buf_ops;
13121253 *block = XFS_BUF_TO_BLOCK(*bpp);
....@@ -1349,7 +1290,7 @@
13491290 /*
13501291 * Copy keys from one btree block to another.
13511292 */
1352
-STATIC void
1293
+void
13531294 xfs_btree_copy_keys(
13541295 struct xfs_btree_cur *cur,
13551296 union xfs_btree_key *dst_key,
....@@ -1377,11 +1318,11 @@
13771318 /*
13781319 * Copy block pointers from one btree block to another.
13791320 */
1380
-STATIC void
1321
+void
13811322 xfs_btree_copy_ptrs(
13821323 struct xfs_btree_cur *cur,
13831324 union xfs_btree_ptr *dst_ptr,
1384
- union xfs_btree_ptr *src_ptr,
1325
+ const union xfs_btree_ptr *src_ptr,
13851326 int numptrs)
13861327 {
13871328 ASSERT(numptrs >= 0);
....@@ -1462,8 +1403,8 @@
14621403 xfs_btree_key_offset(cur, first),
14631404 xfs_btree_key_offset(cur, last + 1) - 1);
14641405 } 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));
14671408 }
14681409 }
14691410
....@@ -1505,8 +1446,8 @@
15051446 xfs_btree_ptr_offset(cur, first, level),
15061447 xfs_btree_ptr_offset(cur, last + 1, level) - 1);
15071448 } 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));
15101451 }
15111452
15121453 }
....@@ -1574,8 +1515,8 @@
15741515 xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
15751516 xfs_trans_log_buf(cur->bc_tp, bp, first, last);
15761517 } 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));
15791520 }
15801521 }
15811522
....@@ -1812,10 +1753,10 @@
18121753
18131754 /* Check the inode owner since the verifiers don't. */
18141755 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) &&
18161757 (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
18171758 be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
1818
- cur->bc_private.b.ip->i_ino)
1759
+ cur->bc_ino.ip->i_ino)
18191760 goto out_bad;
18201761
18211762 /* Did we get the level we were looking for? */
....@@ -1831,6 +1772,7 @@
18311772
18321773 out_bad:
18331774 *blkp = NULL;
1775
+ xfs_buf_mark_corrupt(bp);
18341776 xfs_trans_brelse(cur->bc_tp, bp);
18351777 return -EFSCORRUPTED;
18361778 }
....@@ -1878,7 +1820,7 @@
18781820 XFS_BTREE_STATS_INC(cur, lookup);
18791821
18801822 /* 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))
18821824 return -EFSCORRUPTED;
18831825
18841826 block = NULL;
....@@ -1998,7 +1940,8 @@
19981940 error = xfs_btree_increment(cur, 0, &i);
19991941 if (error)
20001942 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;
20021945 *stat = 1;
20031946 return 0;
20041947 }
....@@ -2419,8 +2362,6 @@
24192362 XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1);
24202363 if (level > 0) {
24212364 /* It's a nonleaf. operate on keys and ptrs */
2422
- int i; /* loop index */
2423
-
24242365 for (i = 0; i < rrecs; i++) {
24252366 error = xfs_btree_debug_check_ptr(cur, rpp, i + 1, level);
24262367 if (error)
....@@ -2453,7 +2394,10 @@
24532394 if (error)
24542395 goto error0;
24552396 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
+ }
24572401
24582402 error = xfs_btree_decrement(tcur, level, &i);
24592403 if (error)
....@@ -2620,7 +2564,10 @@
26202564 if (error)
26212565 goto error0;
26222566 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
+ }
26242571
26252572 error = xfs_btree_increment(tcur, level, &i);
26262573 if (error)
....@@ -2706,7 +2653,7 @@
27062653 XFS_BTREE_STATS_INC(cur, alloc);
27072654
27082655 /* 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);
27102657 if (error)
27112658 goto error0;
27122659
....@@ -2864,7 +2811,7 @@
28642811 struct xfs_btree_split_args *args = container_of(work,
28652812 struct xfs_btree_split_args, work);
28662813 unsigned long pflags;
2867
- unsigned long new_pflags = PF_MEMALLOC_NOFS;
2814
+ unsigned long new_pflags = 0;
28682815
28692816 /*
28702817 * we are in a transaction context here, but may also be doing work
....@@ -2876,12 +2823,20 @@
28762823 new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
28772824
28782825 current_set_flags_nested(&pflags, new_pflags);
2826
+ xfs_trans_set_context(args->cur->bc_tp);
28792827
28802828 args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
28812829 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
+ */
28822838 complete(args->done);
28832839
2884
- current_restore_flags_nested(&pflags, new_pflags);
28852840 }
28862841
28872842 /*
....@@ -2961,7 +2916,7 @@
29612916 XFS_BTREE_STATS_INC(cur, alloc);
29622917
29632918 /* 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);
29652920 if (error)
29662921 goto error0;
29672922
....@@ -3001,9 +2956,9 @@
30012956
30022957 xfs_btree_copy_ptrs(cur, pp, &nptr, 1);
30032958
3004
- xfs_iroot_realloc(cur->bc_private.b.ip,
2959
+ xfs_iroot_realloc(cur->bc_ino.ip,
30052960 1 - xfs_btree_get_numrecs(cblock),
3006
- cur->bc_private.b.whichfork);
2961
+ cur->bc_ino.whichfork);
30072962
30082963 xfs_btree_setbuf(cur, level, cbp);
30092964
....@@ -3016,7 +2971,7 @@
30162971 xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
30172972
30182973 *logflags |=
3019
- XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork);
2974
+ XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork);
30202975 *stat = 1;
30212976 return 0;
30222977 error0:
....@@ -3058,7 +3013,7 @@
30583013 XFS_BTREE_STATS_INC(cur, alloc);
30593014
30603015 /* 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);
30623017 if (error)
30633018 goto error0;
30643019
....@@ -3168,11 +3123,11 @@
31683123
31693124 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
31703125 level == cur->bc_nlevels - 1) {
3171
- struct xfs_inode *ip = cur->bc_private.b.ip;
3126
+ struct xfs_inode *ip = cur->bc_ino.ip;
31723127
31733128 if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {
31743129 /* 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);
31763131 *stat = 1;
31773132 } else {
31783133 /* A root block that needs replacing */
....@@ -3235,7 +3190,7 @@
32353190 struct xfs_btree_block *block; /* btree block */
32363191 struct xfs_buf *bp; /* buffer for block */
32373192 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 */
32393194 union xfs_btree_key nkey; /* new block key */
32403195 union xfs_btree_key *lkey;
32413196 int optr; /* old key/record index */
....@@ -3315,7 +3270,7 @@
33153270 #ifdef DEBUG
33163271 error = xfs_btree_check_block(cur, block, level, bp);
33173272 if (error)
3318
- return error;
3273
+ goto error0;
33193274 #endif
33203275
33213276 /*
....@@ -3335,7 +3290,7 @@
33353290 for (i = numrecs - ptr; i >= 0; i--) {
33363291 error = xfs_btree_debug_check_ptr(cur, pp, i, level);
33373292 if (error)
3338
- return error;
3293
+ goto error0;
33393294 }
33403295
33413296 xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1);
....@@ -3420,6 +3375,8 @@
34203375 return 0;
34213376
34223377 error0:
3378
+ if (ncur)
3379
+ xfs_btree_del_cursor(ncur, error);
34233380 return error;
34243381 }
34253382
....@@ -3474,7 +3431,10 @@
34743431 goto error0;
34753432 }
34763433
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
+ }
34783438 level++;
34793439
34803440 /*
....@@ -3515,8 +3475,8 @@
35153475 xfs_btree_kill_iroot(
35163476 struct xfs_btree_cur *cur)
35173477 {
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;
35203480 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
35213481 struct xfs_btree_block *block;
35223482 struct xfs_btree_block *cblock;
....@@ -3574,8 +3534,8 @@
35743534
35753535 index = numrecs - cur->bc_ops->get_maxrecs(cur, level);
35763536 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);
35793539 block = ifp->if_broot;
35803540 }
35813541
....@@ -3604,7 +3564,7 @@
36043564 cur->bc_bufs[level - 1] = NULL;
36053565 be16_add_cpu(&block->bb_level, -1);
36063566 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));
36083568 cur->bc_nlevels--;
36093569 out0:
36103570 return 0;
....@@ -3772,8 +3732,8 @@
37723732 */
37733733 if (level == cur->bc_nlevels - 1) {
37743734 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);
37773737
37783738 error = xfs_btree_kill_iroot(cur);
37793739 if (error)
....@@ -3878,15 +3838,24 @@
38783838 * Actually any entry but the first would suffice.
38793839 */
38803840 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
+ }
38823845
38833846 error = xfs_btree_increment(tcur, level, &i);
38843847 if (error)
38853848 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
+ }
38873853
38883854 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
+ }
38903859
38913860 /* Grab a pointer to the block. */
38923861 right = xfs_btree_get_block(tcur, level, &rbp);
....@@ -3930,12 +3899,18 @@
39303899 rrecs = xfs_btree_get_numrecs(right);
39313900 if (!xfs_btree_ptr_is_null(cur, &lptr)) {
39323901 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
+ }
39343906
39353907 error = xfs_btree_decrement(tcur, level, &i);
39363908 if (error)
39373909 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
+ }
39393914 }
39403915 }
39413916
....@@ -3949,13 +3924,19 @@
39493924 * previous block.
39503925 */
39513926 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
+ }
39533931
39543932 error = xfs_btree_decrement(tcur, level, &i);
39553933 if (error)
39563934 goto error0;
39573935 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
+ }
39593940
39603941 /* Grab a pointer to the block. */
39613942 left = xfs_btree_get_block(tcur, level, &lbp);
....@@ -4297,6 +4278,7 @@
42974278 xfs_btree_visit_blocks(
42984279 struct xfs_btree_cur *cur,
42994280 xfs_btree_visit_blocks_fn fn,
4281
+ unsigned int flags,
43004282 void *data)
43014283 {
43024284 union xfs_btree_ptr lptr;
....@@ -4322,6 +4304,11 @@
43224304
43234305 /* save for the next iteration of the loop */
43244306 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;
43254312 }
43264313
43274314 /* for each buffer in the level */
....@@ -4424,7 +4411,7 @@
44244411 bbcoi.buffer_list = buffer_list;
44254412
44264413 return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner,
4427
- &bbcoi);
4414
+ XFS_BTREE_VISIT_ALL, &bbcoi);
44284415 }
44294416
44304417 /* Verify the v5 fields of a long-format btree block. */
....@@ -4433,7 +4420,7 @@
44334420 struct xfs_buf *bp,
44344421 uint64_t owner)
44354422 {
4436
- struct xfs_mount *mp = bp->b_target->bt_mount;
4423
+ struct xfs_mount *mp = bp->b_mount;
44374424 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
44384425
44394426 if (!xfs_sb_version_hascrc(&mp->m_sb))
....@@ -4454,7 +4441,7 @@
44544441 struct xfs_buf *bp,
44554442 unsigned int max_recs)
44564443 {
4457
- struct xfs_mount *mp = bp->b_target->bt_mount;
4444
+ struct xfs_mount *mp = bp->b_mount;
44584445 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
44594446
44604447 /* numrecs verification */
....@@ -4477,14 +4464,12 @@
44774464 * btree block
44784465 *
44794466 * @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
44824467 */
44834468 xfs_failaddr_t
44844469 xfs_btree_sblock_v5hdr_verify(
44854470 struct xfs_buf *bp)
44864471 {
4487
- struct xfs_mount *mp = bp->b_target->bt_mount;
4472
+ struct xfs_mount *mp = bp->b_mount;
44884473 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
44894474 struct xfs_perag *pag = bp->b_pag;
44904475
....@@ -4510,7 +4495,7 @@
45104495 struct xfs_buf *bp,
45114496 unsigned int max_recs)
45124497 {
4513
- struct xfs_mount *mp = bp->b_target->bt_mount;
4498
+ struct xfs_mount *mp = bp->b_mount;
45144499 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
45154500 xfs_agblock_t agno;
45164501
....@@ -4611,7 +4596,7 @@
46114596
46124597 /* Callback */
46134598 error = fn(cur, recp, priv);
4614
- if (error < 0 || error == XFS_BTREE_QUERY_RANGE_ABORT)
4599
+ if (error)
46154600 break;
46164601
46174602 advloop:
....@@ -4713,8 +4698,7 @@
47134698 */
47144699 if (ldiff >= 0 && hdiff >= 0) {
47154700 error = fn(cur, recp, priv);
4716
- if (error < 0 ||
4717
- error == XFS_BTREE_QUERY_RANGE_ABORT)
4701
+ if (error)
47184702 break;
47194703 } else if (hdiff < 0) {
47204704 /* Record is larger than high key; pop. */
....@@ -4785,8 +4769,7 @@
47854769 * Query a btree for all records overlapping a given interval of keys. The
47864770 * supplied function will be called with each record found; return one of the
47874771 * 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.
47904773 */
47914774 int
47924775 xfs_btree_query_range(
....@@ -4880,7 +4863,7 @@
48804863 {
48814864 *blocks = 0;
48824865 return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper,
4883
- blocks);
4866
+ XFS_BTREE_VISIT_ALL, blocks);
48844867 }
48854868
48864869 /* Compare two btree pointers. */
....@@ -4902,7 +4885,7 @@
49024885 union xfs_btree_rec *rec,
49034886 void *priv)
49044887 {
4905
- return XFS_BTREE_QUERY_RANGE_ABORT;
4888
+ return -ECANCELED;
49064889 }
49074890
49084891 /* Is there a record covering a given range of keys? */
....@@ -4917,7 +4900,7 @@
49174900
49184901 error = xfs_btree_query_range(cur, low, high,
49194902 &xfs_btree_has_record_helper, NULL);
4920
- if (error == XFS_BTREE_QUERY_RANGE_ABORT) {
4903
+ if (error == -ECANCELED) {
49214904 *exists = true;
49224905 return 0;
49234906 }