117910db51b809ebeea0196182e05f0dd0c54611
[linux-2.6-microblaze.git] / fs / xfs / scrub / btree.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2017 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <darrick.wong@oracle.com>
5  */
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_defer.h"
13 #include "xfs_btree.h"
14 #include "xfs_bit.h"
15 #include "xfs_log_format.h"
16 #include "xfs_trans.h"
17 #include "xfs_sb.h"
18 #include "xfs_inode.h"
19 #include "xfs_alloc.h"
20 #include "scrub/scrub.h"
21 #include "scrub/common.h"
22 #include "scrub/btree.h"
23 #include "scrub/trace.h"
24
25 /* btree scrubbing */
26
27 /*
28  * Check for btree operation errors.  See the section about handling
29  * operational errors in common.c.
30  */
31 static bool
32 __xchk_btree_process_error(
33         struct xfs_scrub        *sc,
34         struct xfs_btree_cur    *cur,
35         int                     level,
36         int                     *error,
37         __u32                   errflag,
38         void                    *ret_ip)
39 {
40         if (*error == 0)
41                 return true;
42
43         switch (*error) {
44         case -EDEADLOCK:
45                 /* Used to restart an op with deadlock avoidance. */
46                 trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
47                 break;
48         case -EFSBADCRC:
49         case -EFSCORRUPTED:
50                 /* Note the badness but don't abort. */
51                 sc->sm->sm_flags |= errflag;
52                 *error = 0;
53                 /* fall through */
54         default:
55                 if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
56                         trace_xchk_ifork_btree_op_error(sc, cur, level,
57                                         *error, ret_ip);
58                 else
59                         trace_xchk_btree_op_error(sc, cur, level,
60                                         *error, ret_ip);
61                 break;
62         }
63         return false;
64 }
65
66 bool
67 xchk_btree_process_error(
68         struct xfs_scrub        *sc,
69         struct xfs_btree_cur    *cur,
70         int                     level,
71         int                     *error)
72 {
73         return __xchk_btree_process_error(sc, cur, level, error,
74                         XFS_SCRUB_OFLAG_CORRUPT, __return_address);
75 }
76
77 bool
78 xchk_btree_xref_process_error(
79         struct xfs_scrub        *sc,
80         struct xfs_btree_cur    *cur,
81         int                     level,
82         int                     *error)
83 {
84         return __xchk_btree_process_error(sc, cur, level, error,
85                         XFS_SCRUB_OFLAG_XFAIL, __return_address);
86 }
87
88 /* Record btree block corruption. */
89 static void
90 __xchk_btree_set_corrupt(
91         struct xfs_scrub        *sc,
92         struct xfs_btree_cur    *cur,
93         int                     level,
94         __u32                   errflag,
95         void                    *ret_ip)
96 {
97         sc->sm->sm_flags |= errflag;
98
99         if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
100                 trace_xchk_ifork_btree_error(sc, cur, level,
101                                 ret_ip);
102         else
103                 trace_xchk_btree_error(sc, cur, level,
104                                 ret_ip);
105 }
106
107 void
108 xchk_btree_set_corrupt(
109         struct xfs_scrub        *sc,
110         struct xfs_btree_cur    *cur,
111         int                     level)
112 {
113         __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_CORRUPT,
114                         __return_address);
115 }
116
117 void
118 xchk_btree_xref_set_corrupt(
119         struct xfs_scrub        *sc,
120         struct xfs_btree_cur    *cur,
121         int                     level)
122 {
123         __xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_XCORRUPT,
124                         __return_address);
125 }
126
127 /*
128  * Make sure this record is in order and doesn't stray outside of the parent
129  * keys.
130  */
131 STATIC void
132 xchk_btree_rec(
133         struct xchk_btree       *bs)
134 {
135         struct xfs_btree_cur    *cur = bs->cur;
136         union xfs_btree_rec     *rec;
137         union xfs_btree_key     key;
138         union xfs_btree_key     hkey;
139         union xfs_btree_key     *keyp;
140         struct xfs_btree_block  *block;
141         struct xfs_btree_block  *keyblock;
142         struct xfs_buf          *bp;
143
144         block = xfs_btree_get_block(cur, 0, &bp);
145         rec = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
146
147         trace_xchk_btree_rec(bs->sc, cur, 0);
148
149         /* If this isn't the first record, are they in order? */
150         if (!bs->firstrec && !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec))
151                 xchk_btree_set_corrupt(bs->sc, cur, 0);
152         bs->firstrec = false;
153         memcpy(&bs->lastrec, rec, cur->bc_ops->rec_len);
154
155         if (cur->bc_nlevels == 1)
156                 return;
157
158         /* Is this at least as large as the parent low key? */
159         cur->bc_ops->init_key_from_rec(&key, rec);
160         keyblock = xfs_btree_get_block(cur, 1, &bp);
161         keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[1], keyblock);
162         if (cur->bc_ops->diff_two_keys(cur, &key, keyp) < 0)
163                 xchk_btree_set_corrupt(bs->sc, cur, 1);
164
165         if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
166                 return;
167
168         /* Is this no larger than the parent high key? */
169         cur->bc_ops->init_high_key_from_rec(&hkey, rec);
170         keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[1], keyblock);
171         if (cur->bc_ops->diff_two_keys(cur, keyp, &hkey) < 0)
172                 xchk_btree_set_corrupt(bs->sc, cur, 1);
173 }
174
175 /*
176  * Make sure this key is in order and doesn't stray outside of the parent
177  * keys.
178  */
179 STATIC void
180 xchk_btree_key(
181         struct xchk_btree       *bs,
182         int                     level)
183 {
184         struct xfs_btree_cur    *cur = bs->cur;
185         union xfs_btree_key     *key;
186         union xfs_btree_key     *keyp;
187         struct xfs_btree_block  *block;
188         struct xfs_btree_block  *keyblock;
189         struct xfs_buf          *bp;
190
191         block = xfs_btree_get_block(cur, level, &bp);
192         key = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block);
193
194         trace_xchk_btree_key(bs->sc, cur, level);
195
196         /* If this isn't the first key, are they in order? */
197         if (!bs->firstkey[level] &&
198             !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level], key))
199                 xchk_btree_set_corrupt(bs->sc, cur, level);
200         bs->firstkey[level] = false;
201         memcpy(&bs->lastkey[level], key, cur->bc_ops->key_len);
202
203         if (level + 1 >= cur->bc_nlevels)
204                 return;
205
206         /* Is this at least as large as the parent low key? */
207         keyblock = xfs_btree_get_block(cur, level + 1, &bp);
208         keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1], keyblock);
209         if (cur->bc_ops->diff_two_keys(cur, key, keyp) < 0)
210                 xchk_btree_set_corrupt(bs->sc, cur, level);
211
212         if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
213                 return;
214
215         /* Is this no larger than the parent high key? */
216         key = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block);
217         keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1], keyblock);
218         if (cur->bc_ops->diff_two_keys(cur, keyp, key) < 0)
219                 xchk_btree_set_corrupt(bs->sc, cur, level);
220 }
221
222 /*
223  * Check a btree pointer.  Returns true if it's ok to use this pointer.
224  * Callers do not need to set the corrupt flag.
225  */
226 static bool
227 xchk_btree_ptr_ok(
228         struct xchk_btree       *bs,
229         int                     level,
230         union xfs_btree_ptr     *ptr)
231 {
232         bool                    res;
233
234         /* A btree rooted in an inode has no block pointer to the root. */
235         if ((bs->cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
236             level == bs->cur->bc_nlevels)
237                 return true;
238
239         /* Otherwise, check the pointers. */
240         if (bs->cur->bc_flags & XFS_BTREE_LONG_PTRS)
241                 res = xfs_btree_check_lptr(bs->cur, be64_to_cpu(ptr->l), level);
242         else
243                 res = xfs_btree_check_sptr(bs->cur, be32_to_cpu(ptr->s), level);
244         if (!res)
245                 xchk_btree_set_corrupt(bs->sc, bs->cur, level);
246
247         return res;
248 }
249
250 /* Check that a btree block's sibling matches what we expect it. */
251 STATIC int
252 xchk_btree_block_check_sibling(
253         struct xchk_btree       *bs,
254         int                     level,
255         int                     direction,
256         union xfs_btree_ptr     *sibling)
257 {
258         struct xfs_btree_cur    *cur = bs->cur;
259         struct xfs_btree_block  *pblock;
260         struct xfs_buf          *pbp;
261         struct xfs_btree_cur    *ncur = NULL;
262         union xfs_btree_ptr     *pp;
263         int                     success;
264         int                     error;
265
266         error = xfs_btree_dup_cursor(cur, &ncur);
267         if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error) ||
268             !ncur)
269                 return error;
270
271         /*
272          * If the pointer is null, we shouldn't be able to move the upper
273          * level pointer anywhere.
274          */
275         if (xfs_btree_ptr_is_null(cur, sibling)) {
276                 if (direction > 0)
277                         error = xfs_btree_increment(ncur, level + 1, &success);
278                 else
279                         error = xfs_btree_decrement(ncur, level + 1, &success);
280                 if (error == 0 && success)
281                         xchk_btree_set_corrupt(bs->sc, cur, level);
282                 error = 0;
283                 goto out;
284         }
285
286         /* Increment upper level pointer. */
287         if (direction > 0)
288                 error = xfs_btree_increment(ncur, level + 1, &success);
289         else
290                 error = xfs_btree_decrement(ncur, level + 1, &success);
291         if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error))
292                 goto out;
293         if (!success) {
294                 xchk_btree_set_corrupt(bs->sc, cur, level + 1);
295                 goto out;
296         }
297
298         /* Compare upper level pointer to sibling pointer. */
299         pblock = xfs_btree_get_block(ncur, level + 1, &pbp);
300         pp = xfs_btree_ptr_addr(ncur, ncur->bc_ptrs[level + 1], pblock);
301         if (!xchk_btree_ptr_ok(bs, level + 1, pp))
302                 goto out;
303         if (pbp)
304                 xchk_buffer_recheck(bs->sc, pbp);
305
306         if (xfs_btree_diff_two_ptrs(cur, pp, sibling))
307                 xchk_btree_set_corrupt(bs->sc, cur, level);
308 out:
309         xfs_btree_del_cursor(ncur, XFS_BTREE_ERROR);
310         return error;
311 }
312
313 /* Check the siblings of a btree block. */
314 STATIC int
315 xchk_btree_block_check_siblings(
316         struct xchk_btree       *bs,
317         struct xfs_btree_block  *block)
318 {
319         struct xfs_btree_cur    *cur = bs->cur;
320         union xfs_btree_ptr     leftsib;
321         union xfs_btree_ptr     rightsib;
322         int                     level;
323         int                     error = 0;
324
325         xfs_btree_get_sibling(cur, block, &leftsib, XFS_BB_LEFTSIB);
326         xfs_btree_get_sibling(cur, block, &rightsib, XFS_BB_RIGHTSIB);
327         level = xfs_btree_get_level(block);
328
329         /* Root block should never have siblings. */
330         if (level == cur->bc_nlevels - 1) {
331                 if (!xfs_btree_ptr_is_null(cur, &leftsib) ||
332                     !xfs_btree_ptr_is_null(cur, &rightsib))
333                         xchk_btree_set_corrupt(bs->sc, cur, level);
334                 goto out;
335         }
336
337         /*
338          * Does the left & right sibling pointers match the adjacent
339          * parent level pointers?
340          * (These function absorbs error codes for us.)
341          */
342         error = xchk_btree_block_check_sibling(bs, level, -1, &leftsib);
343         if (error)
344                 return error;
345         error = xchk_btree_block_check_sibling(bs, level, 1, &rightsib);
346         if (error)
347                 return error;
348 out:
349         return error;
350 }
351
352 struct check_owner {
353         struct list_head        list;
354         xfs_daddr_t             daddr;
355         int                     level;
356 };
357
358 /*
359  * Make sure this btree block isn't in the free list and that there's
360  * an rmap record for it.
361  */
362 STATIC int
363 xchk_btree_check_block_owner(
364         struct xchk_btree       *bs,
365         int                     level,
366         xfs_daddr_t             daddr)
367 {
368         xfs_agnumber_t          agno;
369         xfs_agblock_t           agbno;
370         xfs_btnum_t             btnum;
371         bool                    init_sa;
372         int                     error = 0;
373
374         if (!bs->cur)
375                 return 0;
376
377         btnum = bs->cur->bc_btnum;
378         agno = xfs_daddr_to_agno(bs->cur->bc_mp, daddr);
379         agbno = xfs_daddr_to_agbno(bs->cur->bc_mp, daddr);
380
381         init_sa = bs->cur->bc_flags & XFS_BTREE_LONG_PTRS;
382         if (init_sa) {
383                 error = xchk_ag_init(bs->sc, agno, &bs->sc->sa);
384                 if (!xchk_btree_xref_process_error(bs->sc, bs->cur,
385                                 level, &error))
386                         return error;
387         }
388
389         xchk_xref_is_used_space(bs->sc, agbno, 1);
390         /*
391          * The bnobt scrubber aliases bs->cur to bs->sc->sa.bno_cur, so we
392          * have to nullify it (to shut down further block owner checks) if
393          * self-xref encounters problems.
394          */
395         if (!bs->sc->sa.bno_cur && btnum == XFS_BTNUM_BNO)
396                 bs->cur = NULL;
397
398         xchk_xref_is_owned_by(bs->sc, agbno, 1, bs->oinfo);
399         if (!bs->sc->sa.rmap_cur && btnum == XFS_BTNUM_RMAP)
400                 bs->cur = NULL;
401
402         if (init_sa)
403                 xchk_ag_free(bs->sc, &bs->sc->sa);
404
405         return error;
406 }
407
408 /* Check the owner of a btree block. */
409 STATIC int
410 xchk_btree_check_owner(
411         struct xchk_btree       *bs,
412         int                     level,
413         struct xfs_buf          *bp)
414 {
415         struct xfs_btree_cur    *cur = bs->cur;
416         struct check_owner      *co;
417
418         /*
419          * In theory, xfs_btree_get_block should only give us a null buffer
420          * pointer for the root of a root-in-inode btree type, but we need
421          * to check defensively here in case the cursor state is also screwed
422          * up.
423          */
424         if (bp == NULL) {
425                 if (!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE))
426                         xchk_btree_set_corrupt(bs->sc, bs->cur, level);
427                 return 0;
428         }
429
430         /*
431          * We want to cross-reference each btree block with the bnobt
432          * and the rmapbt.  We cannot cross-reference the bnobt or
433          * rmapbt while scanning the bnobt or rmapbt, respectively,
434          * because we cannot alter the cursor and we'd prefer not to
435          * duplicate cursors.  Therefore, save the buffer daddr for
436          * later scanning.
437          */
438         if (cur->bc_btnum == XFS_BTNUM_BNO || cur->bc_btnum == XFS_BTNUM_RMAP) {
439                 co = kmem_alloc(sizeof(struct check_owner),
440                                 KM_MAYFAIL);
441                 if (!co)
442                         return -ENOMEM;
443                 co->level = level;
444                 co->daddr = XFS_BUF_ADDR(bp);
445                 list_add_tail(&co->list, &bs->to_check);
446                 return 0;
447         }
448
449         return xchk_btree_check_block_owner(bs, level, XFS_BUF_ADDR(bp));
450 }
451
452 /*
453  * Check that this btree block has at least minrecs records or is one of the
454  * special blocks that don't require that.
455  */
456 STATIC void
457 xchk_btree_check_minrecs(
458         struct xchk_btree       *bs,
459         int                     level,
460         struct xfs_btree_block  *block)
461 {
462         unsigned int            numrecs;
463         int                     ok_level;
464
465         numrecs = be16_to_cpu(block->bb_numrecs);
466
467         /* More records than minrecs means the block is ok. */
468         if (numrecs >= bs->cur->bc_ops->get_minrecs(bs->cur, level))
469                 return;
470
471         /*
472          * Certain btree blocks /can/ have fewer than minrecs records.  Any
473          * level greater than or equal to the level of the highest dedicated
474          * btree block are allowed to violate this constraint.
475          *
476          * For a btree rooted in a block, the btree root can have fewer than
477          * minrecs records.  If the btree is rooted in an inode and does not
478          * store records in the root, the direct children of the root and the
479          * root itself can have fewer than minrecs records.
480          */
481         ok_level = bs->cur->bc_nlevels - 1;
482         if (bs->cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
483                 ok_level--;
484         if (level >= ok_level)
485                 return;
486
487         xchk_btree_set_corrupt(bs->sc, bs->cur, level);
488 }
489
490 /*
491  * Grab and scrub a btree block given a btree pointer.  Returns block
492  * and buffer pointers (if applicable) if they're ok to use.
493  */
494 STATIC int
495 xchk_btree_get_block(
496         struct xchk_btree       *bs,
497         int                     level,
498         union xfs_btree_ptr     *pp,
499         struct xfs_btree_block  **pblock,
500         struct xfs_buf          **pbp)
501 {
502         xfs_failaddr_t          failed_at;
503         int                     error;
504
505         *pblock = NULL;
506         *pbp = NULL;
507
508         error = xfs_btree_lookup_get_block(bs->cur, level, pp, pblock);
509         if (!xchk_btree_process_error(bs->sc, bs->cur, level, &error) ||
510             !*pblock)
511                 return error;
512
513         xfs_btree_get_block(bs->cur, level, pbp);
514         if (bs->cur->bc_flags & XFS_BTREE_LONG_PTRS)
515                 failed_at = __xfs_btree_check_lblock(bs->cur, *pblock,
516                                 level, *pbp);
517         else
518                 failed_at = __xfs_btree_check_sblock(bs->cur, *pblock,
519                                  level, *pbp);
520         if (failed_at) {
521                 xchk_btree_set_corrupt(bs->sc, bs->cur, level);
522                 return 0;
523         }
524         if (*pbp)
525                 xchk_buffer_recheck(bs->sc, *pbp);
526
527         xchk_btree_check_minrecs(bs, level, *pblock);
528
529         /*
530          * Check the block's owner; this function absorbs error codes
531          * for us.
532          */
533         error = xchk_btree_check_owner(bs, level, *pbp);
534         if (error)
535                 return error;
536
537         /*
538          * Check the block's siblings; this function absorbs error codes
539          * for us.
540          */
541         return xchk_btree_block_check_siblings(bs, *pblock);
542 }
543
544 /*
545  * Check that the low and high keys of this block match the keys stored
546  * in the parent block.
547  */
548 STATIC void
549 xchk_btree_block_keys(
550         struct xchk_btree       *bs,
551         int                     level,
552         struct xfs_btree_block  *block)
553 {
554         union xfs_btree_key     block_keys;
555         struct xfs_btree_cur    *cur = bs->cur;
556         union xfs_btree_key     *high_bk;
557         union xfs_btree_key     *parent_keys;
558         union xfs_btree_key     *high_pk;
559         struct xfs_btree_block  *parent_block;
560         struct xfs_buf          *bp;
561
562         if (level >= cur->bc_nlevels - 1)
563                 return;
564
565         /* Calculate the keys for this block. */
566         xfs_btree_get_keys(cur, block, &block_keys);
567
568         /* Obtain the parent's copy of the keys for this block. */
569         parent_block = xfs_btree_get_block(cur, level + 1, &bp);
570         parent_keys = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1],
571                         parent_block);
572
573         if (cur->bc_ops->diff_two_keys(cur, &block_keys, parent_keys) != 0)
574                 xchk_btree_set_corrupt(bs->sc, cur, 1);
575
576         if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
577                 return;
578
579         /* Get high keys */
580         high_bk = xfs_btree_high_key_from_key(cur, &block_keys);
581         high_pk = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1],
582                         parent_block);
583
584         if (cur->bc_ops->diff_two_keys(cur, high_bk, high_pk) != 0)
585                 xchk_btree_set_corrupt(bs->sc, cur, 1);
586 }
587
588 /*
589  * Visit all nodes and leaves of a btree.  Check that all pointers and
590  * records are in order, that the keys reflect the records, and use a callback
591  * so that the caller can verify individual records.
592  */
593 int
594 xchk_btree(
595         struct xfs_scrub                *sc,
596         struct xfs_btree_cur            *cur,
597         xchk_btree_rec_fn               scrub_fn,
598         const struct xfs_owner_info     *oinfo,
599         void                            *private)
600 {
601         struct xchk_btree               bs = {
602                 .cur                    = cur,
603                 .scrub_rec              = scrub_fn,
604                 .oinfo                  = oinfo,
605                 .firstrec               = true,
606                 .private                = private,
607                 .sc                     = sc,
608         };
609         union xfs_btree_ptr             ptr;
610         union xfs_btree_ptr             *pp;
611         union xfs_btree_rec             *recp;
612         struct xfs_btree_block          *block;
613         int                             level;
614         struct xfs_buf                  *bp;
615         struct check_owner              *co;
616         struct check_owner              *n;
617         int                             i;
618         int                             error = 0;
619
620         /* Initialize scrub state */
621         for (i = 0; i < XFS_BTREE_MAXLEVELS; i++)
622                 bs.firstkey[i] = true;
623         INIT_LIST_HEAD(&bs.to_check);
624
625         /* Don't try to check a tree with a height we can't handle. */
626         if (cur->bc_nlevels > XFS_BTREE_MAXLEVELS) {
627                 xchk_btree_set_corrupt(sc, cur, 0);
628                 goto out;
629         }
630
631         /*
632          * Load the root of the btree.  The helper function absorbs
633          * error codes for us.
634          */
635         level = cur->bc_nlevels - 1;
636         cur->bc_ops->init_ptr_from_cur(cur, &ptr);
637         if (!xchk_btree_ptr_ok(&bs, cur->bc_nlevels, &ptr))
638                 goto out;
639         error = xchk_btree_get_block(&bs, level, &ptr, &block, &bp);
640         if (error || !block)
641                 goto out;
642
643         cur->bc_ptrs[level] = 1;
644
645         while (level < cur->bc_nlevels) {
646                 block = xfs_btree_get_block(cur, level, &bp);
647
648                 if (level == 0) {
649                         /* End of leaf, pop back towards the root. */
650                         if (cur->bc_ptrs[level] >
651                             be16_to_cpu(block->bb_numrecs)) {
652                                 xchk_btree_block_keys(&bs, level, block);
653                                 if (level < cur->bc_nlevels - 1)
654                                         cur->bc_ptrs[level + 1]++;
655                                 level++;
656                                 continue;
657                         }
658
659                         /* Records in order for scrub? */
660                         xchk_btree_rec(&bs);
661
662                         /* Call out to the record checker. */
663                         recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
664                         error = bs.scrub_rec(&bs, recp);
665                         if (error)
666                                 break;
667                         if (xchk_should_terminate(sc, &error) ||
668                             (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
669                                 break;
670
671                         cur->bc_ptrs[level]++;
672                         continue;
673                 }
674
675                 /* End of node, pop back towards the root. */
676                 if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) {
677                         xchk_btree_block_keys(&bs, level, block);
678                         if (level < cur->bc_nlevels - 1)
679                                 cur->bc_ptrs[level + 1]++;
680                         level++;
681                         continue;
682                 }
683
684                 /* Keys in order for scrub? */
685                 xchk_btree_key(&bs, level);
686
687                 /* Drill another level deeper. */
688                 pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block);
689                 if (!xchk_btree_ptr_ok(&bs, level, pp)) {
690                         cur->bc_ptrs[level]++;
691                         continue;
692                 }
693                 level--;
694                 error = xchk_btree_get_block(&bs, level, pp, &block, &bp);
695                 if (error || !block)
696                         goto out;
697
698                 cur->bc_ptrs[level] = 1;
699         }
700
701 out:
702         /* Process deferred owner checks on btree blocks. */
703         list_for_each_entry_safe(co, n, &bs.to_check, list) {
704                 if (!error && bs.cur)
705                         error = xchk_btree_check_block_owner(&bs,
706                                         co->level, co->daddr);
707                 list_del(&co->list);
708                 kmem_free(co);
709         }
710
711         return error;
712 }