xref: /linux/fs/xfs/scrub/btree.c (revision 49869d5d0356c9468621de24d49bac43b7893782)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #include "xfs_platform.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_inode.h"
13 #include "xfs_btree.h"
14 #include "scrub/scrub.h"
15 #include "scrub/common.h"
16 #include "scrub/btree.h"
17 #include "scrub/trace.h"
18 
19 /* btree scrubbing */
20 
21 /*
22  * Check for btree operation errors.  See the section about handling
23  * operational errors in common.c.
24  */
25 static bool
26 __xchk_btree_process_error(
27 	struct xfs_scrub	*sc,
28 	struct xfs_btree_cur	*cur,
29 	int			level,
30 	int			*error,
31 	__u32			errflag,
32 	void			*ret_ip)
33 {
34 	if (*error == 0)
35 		return true;
36 
37 	switch (*error) {
38 	case -EDEADLOCK:
39 	case -ECHRNG:
40 		/* Used to restart an op with deadlock avoidance. */
41 		trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
42 		break;
43 	case -EFSBADCRC:
44 	case -EFSCORRUPTED:
45 	case -EIO:
46 	case -ENODATA:
47 		/* Note the badness but don't abort. */
48 		sc->sm->sm_flags |= errflag;
49 		if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
50 			trace_xchk_ifork_btree_op_error(sc, cur, level,
51 					*error, ret_ip);
52 		else
53 			trace_xchk_btree_op_error(sc, cur, level,
54 					*error, ret_ip);
55 		*error = 0;
56 		break;
57 	default:
58 		if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
59 			trace_xchk_ifork_btree_op_error(sc, cur, level,
60 					*error, ret_ip);
61 		else
62 			trace_xchk_btree_op_error(sc, cur, level,
63 					*error, ret_ip);
64 		break;
65 	}
66 	return false;
67 }
68 
69 bool
70 xchk_btree_process_error(
71 	struct xfs_scrub	*sc,
72 	struct xfs_btree_cur	*cur,
73 	int			level,
74 	int			*error)
75 {
76 	return __xchk_btree_process_error(sc, cur, level, error,
77 			XFS_SCRUB_OFLAG_CORRUPT, __return_address);
78 }
79 
80 bool
81 xchk_btree_xref_process_error(
82 	struct xfs_scrub	*sc,
83 	struct xfs_btree_cur	*cur,
84 	int			level,
85 	int			*error)
86 {
87 	return __xchk_btree_process_error(sc, cur, level, error,
88 			XFS_SCRUB_OFLAG_XFAIL, __return_address);
89 }
90 
91 /* Record btree block corruption. */
92 static void
93 __xchk_btree_set_corrupt(
94 	struct xfs_scrub	*sc,
95 	struct xfs_btree_cur	*cur,
96 	int			level,
97 	__u32			errflag,
98 	void			*ret_ip)
99 {
100 	sc->sm->sm_flags |= errflag;
101 
102 	if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE)
103 		trace_xchk_ifork_btree_error(sc, cur, level,
104 				ret_ip);
105 	else
106 		trace_xchk_btree_error(sc, cur, level,
107 				ret_ip);
108 }
109 
110 void
111 xchk_btree_set_corrupt(
112 	struct xfs_scrub	*sc,
113 	struct xfs_btree_cur	*cur,
114 	int			level)
115 {
116 	__xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_CORRUPT,
117 			__return_address);
118 }
119 
120 void
121 xchk_btree_xref_set_corrupt(
122 	struct xfs_scrub	*sc,
123 	struct xfs_btree_cur	*cur,
124 	int			level)
125 {
126 	__xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_XCORRUPT,
127 			__return_address);
128 }
129 
130 void
131 xchk_btree_set_preen(
132 	struct xfs_scrub	*sc,
133 	struct xfs_btree_cur	*cur,
134 	int			level)
135 {
136 	__xchk_btree_set_corrupt(sc, cur, level, XFS_SCRUB_OFLAG_PREEN,
137 			__return_address);
138 }
139 
140 /*
141  * Make sure this record is in order and doesn't stray outside of the parent
142  * keys.
143  */
144 STATIC void
145 xchk_btree_rec(
146 	struct xchk_btree	*bs)
147 {
148 	struct xfs_btree_cur	*cur = bs->cur;
149 	union xfs_btree_rec	*rec;
150 	union xfs_btree_key	key;
151 	union xfs_btree_key	hkey;
152 	union xfs_btree_key	*keyp;
153 	struct xfs_btree_block	*block;
154 	struct xfs_btree_block	*keyblock;
155 	struct xfs_buf		*bp;
156 
157 	block = xfs_btree_get_block(cur, 0, &bp);
158 	rec = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, block);
159 
160 	trace_xchk_btree_rec(bs->sc, cur, 0);
161 
162 	/* Are all records across all record blocks in order? */
163 	if (bs->lastrec_valid &&
164 	    !cur->bc_ops->recs_inorder(cur, &bs->lastrec, rec))
165 		xchk_btree_set_corrupt(bs->sc, cur, 0);
166 	memcpy(&bs->lastrec, rec, cur->bc_ops->rec_len);
167 	bs->lastrec_valid = true;
168 
169 	if (cur->bc_nlevels == 1)
170 		return;
171 
172 	/* Is low_key(rec) at least as large as the parent low key? */
173 	cur->bc_ops->init_key_from_rec(&key, rec);
174 	keyblock = xfs_btree_get_block(cur, 1, &bp);
175 	keyp = xfs_btree_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
176 	if (xfs_btree_keycmp_lt(cur, &key, keyp))
177 		xchk_btree_set_corrupt(bs->sc, cur, 1);
178 
179 	if (!(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
180 		return;
181 
182 	/* Is high_key(rec) no larger than the parent high key? */
183 	cur->bc_ops->init_high_key_from_rec(&hkey, rec);
184 	keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
185 	if (xfs_btree_keycmp_lt(cur, keyp, &hkey))
186 		xchk_btree_set_corrupt(bs->sc, cur, 1);
187 }
188 
189 /*
190  * Make sure this key is in order and doesn't stray outside of the parent
191  * keys.
192  */
193 STATIC void
194 xchk_btree_key(
195 	struct xchk_btree	*bs,
196 	int			level)
197 {
198 	struct xfs_btree_cur	*cur = bs->cur;
199 	union xfs_btree_key	*key;
200 	union xfs_btree_key	*keyp;
201 	struct xfs_btree_block	*block;
202 	struct xfs_btree_block	*keyblock;
203 	struct xfs_buf		*bp;
204 
205 	block = xfs_btree_get_block(cur, level, &bp);
206 	key = xfs_btree_key_addr(cur, cur->bc_levels[level].ptr, block);
207 
208 	trace_xchk_btree_key(bs->sc, cur, level);
209 
210 	/* Are all low keys across all node blocks in order? */
211 	if (bs->lastkey[level - 1].valid &&
212 	    !cur->bc_ops->keys_inorder(cur, &bs->lastkey[level - 1].key, key))
213 		xchk_btree_set_corrupt(bs->sc, cur, level);
214 	memcpy(&bs->lastkey[level - 1].key, key, cur->bc_ops->key_len);
215 	bs->lastkey[level - 1].valid = true;
216 
217 	if (level + 1 >= cur->bc_nlevels)
218 		return;
219 
220 	/* Is this block's low key at least as large as the parent low key? */
221 	keyblock = xfs_btree_get_block(cur, level + 1, &bp);
222 	keyp = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr, keyblock);
223 	if (xfs_btree_keycmp_lt(cur, key, keyp))
224 		xchk_btree_set_corrupt(bs->sc, cur, level);
225 
226 	if (!(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
227 		return;
228 
229 	/* Is this block's high key no larger than the parent high key? */
230 	key = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, block);
231 	keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr,
232 			keyblock);
233 	if (xfs_btree_keycmp_lt(cur, keyp, key))
234 		xchk_btree_set_corrupt(bs->sc, cur, level);
235 }
236 
237 /*
238  * Check a btree pointer.  Returns true if it's ok to use this pointer.
239  * Callers do not need to set the corrupt flag.
240  */
241 static bool
242 xchk_btree_ptr_ok(
243 	struct xchk_btree	*bs,
244 	int			level,
245 	union xfs_btree_ptr	*ptr)
246 {
247 	/* A btree rooted in an inode has no block pointer to the root. */
248 	if (bs->cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
249 	    level == bs->cur->bc_nlevels)
250 		return true;
251 
252 	/* Otherwise, check the pointers. */
253 	if (__xfs_btree_check_ptr(bs->cur, ptr, 0, level)) {
254 		xchk_btree_set_corrupt(bs->sc, bs->cur, level);
255 		return false;
256 	}
257 
258 	return true;
259 }
260 
261 /* Check that a btree block's sibling matches what we expect it. */
262 STATIC int
263 xchk_btree_block_check_sibling(
264 	struct xchk_btree	*bs,
265 	int			level,
266 	int			direction,
267 	union xfs_btree_ptr	*sibling)
268 {
269 	struct xfs_btree_cur	*cur = bs->cur;
270 	struct xfs_btree_block	*pblock;
271 	struct xfs_buf		*pbp;
272 	struct xfs_btree_cur	*ncur = NULL;
273 	union xfs_btree_ptr	*pp;
274 	int			success;
275 	int			error;
276 
277 	error = xfs_btree_dup_cursor(cur, &ncur);
278 	if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error) ||
279 	    !ncur)
280 		return error;
281 
282 	/*
283 	 * If the pointer is null, we shouldn't be able to move the upper
284 	 * level pointer anywhere.
285 	 */
286 	if (xfs_btree_ptr_is_null(cur, sibling)) {
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 (error == 0 && success)
292 			xchk_btree_set_corrupt(bs->sc, cur, level);
293 		error = 0;
294 		goto out;
295 	}
296 
297 	/* Increment upper level pointer. */
298 	if (direction > 0)
299 		error = xfs_btree_increment(ncur, level + 1, &success);
300 	else
301 		error = xfs_btree_decrement(ncur, level + 1, &success);
302 	if (!xchk_btree_process_error(bs->sc, cur, level + 1, &error))
303 		goto out;
304 	if (!success) {
305 		xchk_btree_set_corrupt(bs->sc, cur, level + 1);
306 		goto out;
307 	}
308 
309 	/* Compare upper level pointer to sibling pointer. */
310 	pblock = xfs_btree_get_block(ncur, level + 1, &pbp);
311 	pp = xfs_btree_ptr_addr(ncur, ncur->bc_levels[level + 1].ptr, pblock);
312 	if (!xchk_btree_ptr_ok(bs, level + 1, pp))
313 		goto out;
314 	if (pbp)
315 		xchk_buffer_recheck(bs->sc, pbp);
316 
317 	if (xfs_btree_cmp_two_ptrs(cur, pp, sibling))
318 		xchk_btree_set_corrupt(bs->sc, cur, level);
319 out:
320 	xfs_btree_del_cursor(ncur, XFS_BTREE_ERROR);
321 	return error;
322 }
323 
324 /* Check the siblings of a btree block. */
325 STATIC int
326 xchk_btree_block_check_siblings(
327 	struct xchk_btree	*bs,
328 	struct xfs_btree_block	*block)
329 {
330 	struct xfs_btree_cur	*cur = bs->cur;
331 	union xfs_btree_ptr	leftsib;
332 	union xfs_btree_ptr	rightsib;
333 	int			level;
334 	int			error = 0;
335 
336 	xfs_btree_get_sibling(cur, block, &leftsib, XFS_BB_LEFTSIB);
337 	xfs_btree_get_sibling(cur, block, &rightsib, XFS_BB_RIGHTSIB);
338 	level = xfs_btree_get_level(block);
339 
340 	/* Root block should never have siblings. */
341 	if (level == cur->bc_nlevels - 1) {
342 		if (!xfs_btree_ptr_is_null(cur, &leftsib) ||
343 		    !xfs_btree_ptr_is_null(cur, &rightsib))
344 			xchk_btree_set_corrupt(bs->sc, cur, level);
345 		goto out;
346 	}
347 
348 	/*
349 	 * Does the left & right sibling pointers match the adjacent
350 	 * parent level pointers?
351 	 * (These function absorbs error codes for us.)
352 	 */
353 	error = xchk_btree_block_check_sibling(bs, level, -1, &leftsib);
354 	if (error)
355 		return error;
356 	error = xchk_btree_block_check_sibling(bs, level, 1, &rightsib);
357 	if (error)
358 		return error;
359 out:
360 	return error;
361 }
362 
363 struct check_owner {
364 	struct list_head	list;
365 	xfs_daddr_t		daddr;
366 	int			level;
367 };
368 
369 /*
370  * Make sure this btree block isn't in the free list and that there's
371  * an rmap record for it.
372  */
373 STATIC int
374 xchk_btree_check_block_owner(
375 	struct xchk_btree	*bs,
376 	int			level,
377 	xfs_daddr_t		daddr)
378 {
379 	xfs_agnumber_t		agno;
380 	xfs_agblock_t		agbno;
381 	bool			is_bnobt, is_rmapbt;
382 	bool			init_sa;
383 	int			error = 0;
384 
385 	if (!bs->cur)
386 		return 0;
387 
388 	is_bnobt = xfs_btree_is_bno(bs->cur->bc_ops);
389 	is_rmapbt = xfs_btree_is_rmap(bs->cur->bc_ops);
390 	agno = xfs_daddr_to_agno(bs->cur->bc_mp, daddr);
391 	agbno = xfs_daddr_to_agbno(bs->cur->bc_mp, daddr);
392 
393 	/*
394 	 * If the btree being examined is not itself a per-AG btree, initialize
395 	 * sc->sa so that we can check for the presence of an ownership record
396 	 * in the rmap btree for the AG containing the block.
397 	 */
398 	init_sa = bs->cur->bc_ops->type != XFS_BTREE_TYPE_AG;
399 	if (init_sa) {
400 		error = xchk_ag_init_existing(bs->sc, agno);
401 		if (!xchk_btree_xref_process_error(bs->sc, bs->cur,
402 				level, &error))
403 			goto out_free;
404 	}
405 
406 	xchk_xref_is_used_space(bs->sc, agbno, 1);
407 	/*
408 	 * The bnobt scrubber aliases bs->cur to bs->sc->sa.bno_cur, so we
409 	 * have to nullify it (to shut down further block owner checks) if
410 	 * self-xref encounters problems.
411 	 */
412 	if (!bs->sc->sa.bno_cur && is_bnobt)
413 		bs->cur = NULL;
414 
415 	xchk_xref_is_only_owned_by(bs->sc, agbno, 1, bs->oinfo);
416 	if (!bs->sc->sa.rmap_cur && is_rmapbt)
417 		bs->cur = NULL;
418 
419 out_free:
420 	if (init_sa)
421 		xchk_ag_free(bs->sc);
422 
423 	return error;
424 }
425 
426 /* Check the owner of a btree block. */
427 STATIC int
428 xchk_btree_check_owner(
429 	struct xchk_btree	*bs,
430 	int			level,
431 	struct xfs_buf		*bp)
432 {
433 	struct xfs_btree_cur	*cur = bs->cur;
434 
435 	/*
436 	 * In theory, xfs_btree_get_block should only give us a null buffer
437 	 * pointer for the root of a root-in-inode btree type, but we need
438 	 * to check defensively here in case the cursor state is also screwed
439 	 * up.
440 	 */
441 	if (bp == NULL) {
442 		if (cur->bc_ops->type != XFS_BTREE_TYPE_INODE)
443 			xchk_btree_set_corrupt(bs->sc, bs->cur, level);
444 		return 0;
445 	}
446 
447 	/*
448 	 * We want to cross-reference each btree block with the bnobt
449 	 * and the rmapbt.  We cannot cross-reference the bnobt or
450 	 * rmapbt while scanning the bnobt or rmapbt, respectively,
451 	 * because we cannot alter the cursor and we'd prefer not to
452 	 * duplicate cursors.  Therefore, save the buffer daddr for
453 	 * later scanning.
454 	 */
455 	if (xfs_btree_is_bno(cur->bc_ops) || xfs_btree_is_rmap(cur->bc_ops)) {
456 		struct check_owner	*co;
457 
458 		co = kmalloc_obj(struct check_owner, XCHK_GFP_FLAGS);
459 		if (!co)
460 			return -ENOMEM;
461 
462 		INIT_LIST_HEAD(&co->list);
463 		co->level = level;
464 		co->daddr = xfs_buf_daddr(bp);
465 		list_add_tail(&co->list, &bs->to_check);
466 		return 0;
467 	}
468 
469 	return xchk_btree_check_block_owner(bs, level, xfs_buf_daddr(bp));
470 }
471 
472 /* Decide if we want to check minrecs of a btree block in the inode root. */
473 static inline bool
474 xchk_btree_check_iroot_minrecs(
475 	struct xchk_btree	*bs)
476 {
477 	/*
478 	 * xfs_bmap_add_attrfork_btree had an implementation bug wherein it
479 	 * would miscalculate the space required for the data fork bmbt root
480 	 * when adding an attr fork, and promote the iroot contents to an
481 	 * external block unnecessarily.  This went unnoticed for many years
482 	 * until scrub found filesystems in this state.  Inode rooted btrees are
483 	 * not supposed to have immediate child blocks that are small enough
484 	 * that the contents could fit in the inode root, but we can't fail
485 	 * existing filesystems, so instead we disable the check for data fork
486 	 * bmap btrees when there's an attr fork.
487 	 */
488 	if (xfs_btree_is_bmap(bs->cur->bc_ops) &&
489 	    bs->cur->bc_ino.whichfork == XFS_DATA_FORK &&
490 	    xfs_inode_has_attr_fork(bs->sc->ip))
491 		return false;
492 
493 	return true;
494 }
495 
496 /*
497  * Check that this btree block has at least minrecs records or is one of the
498  * special blocks that don't require that.
499  */
500 STATIC void
501 xchk_btree_check_minrecs(
502 	struct xchk_btree	*bs,
503 	int			level,
504 	struct xfs_btree_block	*block)
505 {
506 	struct xfs_btree_cur	*cur = bs->cur;
507 	unsigned int		root_level = cur->bc_nlevels - 1;
508 	unsigned int		numrecs = be16_to_cpu(block->bb_numrecs);
509 
510 	/* More records than minrecs means the block is ok. */
511 	if (numrecs >= cur->bc_ops->get_minrecs(cur, level))
512 		return;
513 
514 	/*
515 	 * For btrees rooted in the inode, it's possible that the root block
516 	 * contents spilled into a regular ondisk block because there wasn't
517 	 * enough space in the inode root.  The number of records in that
518 	 * child block might be less than the standard minrecs, but that's ok
519 	 * provided that there's only one direct child of the root.
520 	 */
521 	if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
522 	    level == cur->bc_nlevels - 2) {
523 		struct xfs_btree_block	*root_block;
524 		struct xfs_buf		*root_bp;
525 		int			root_maxrecs;
526 
527 		root_block = xfs_btree_get_block(cur, root_level, &root_bp);
528 		root_maxrecs = cur->bc_ops->get_dmaxrecs(cur, root_level);
529 		if (xchk_btree_check_iroot_minrecs(bs) &&
530 		    (be16_to_cpu(root_block->bb_numrecs) != 1 ||
531 		     numrecs <= root_maxrecs))
532 			xchk_btree_set_corrupt(bs->sc, cur, level);
533 		return;
534 	}
535 
536 	/*
537 	 * Otherwise, only the root level is allowed to have fewer than minrecs
538 	 * records or keyptrs.
539 	 */
540 	if (level < root_level)
541 		xchk_btree_set_corrupt(bs->sc, cur, level);
542 }
543 
544 /*
545  * If this btree block has a parent, make sure that the parent's keys capture
546  * the keyspace contained in this block.
547  */
548 STATIC void
549 xchk_btree_block_check_keys(
550 	struct xchk_btree	*bs,
551 	int			level,
552 	struct xfs_btree_block	*block)
553 {
554 	union xfs_btree_key	block_key;
555 	union xfs_btree_key	*block_high_key;
556 	union xfs_btree_key	*parent_low_key, *parent_high_key;
557 	struct xfs_btree_cur	*cur = bs->cur;
558 	struct xfs_btree_block	*parent_block;
559 	struct xfs_buf		*bp;
560 
561 	if (level == cur->bc_nlevels - 1)
562 		return;
563 
564 	xfs_btree_get_keys(cur, block, &block_key);
565 
566 	/* Make sure the low key of this block matches the parent. */
567 	parent_block = xfs_btree_get_block(cur, level + 1, &bp);
568 	parent_low_key = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr,
569 			parent_block);
570 	if (xfs_btree_keycmp_ne(cur, &block_key, parent_low_key)) {
571 		xchk_btree_set_corrupt(bs->sc, bs->cur, level);
572 		return;
573 	}
574 
575 	if (!(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
576 		return;
577 
578 	/* Make sure the high key of this block matches the parent. */
579 	parent_high_key = xfs_btree_high_key_addr(cur,
580 			cur->bc_levels[level + 1].ptr, parent_block);
581 	block_high_key = xfs_btree_high_key_from_key(cur, &block_key);
582 	if (xfs_btree_keycmp_ne(cur, block_high_key, parent_high_key))
583 		xchk_btree_set_corrupt(bs->sc, bs->cur, level);
584 }
585 
586 /*
587  * Grab and scrub a btree block given a btree pointer.  Returns block
588  * and buffer pointers (if applicable) if they're ok to use.
589  */
590 STATIC int
591 xchk_btree_get_block(
592 	struct xchk_btree	*bs,
593 	int			level,
594 	union xfs_btree_ptr	*pp,
595 	struct xfs_btree_block	**pblock,
596 	struct xfs_buf		**pbp)
597 {
598 	int			error;
599 
600 	*pblock = NULL;
601 	*pbp = NULL;
602 
603 	error = xfs_btree_lookup_get_block(bs->cur, level, pp, pblock);
604 	if (!xchk_btree_process_error(bs->sc, bs->cur, level, &error) ||
605 	    !*pblock)
606 		return error;
607 
608 	xfs_btree_get_block(bs->cur, level, pbp);
609 	if (__xfs_btree_check_block(bs->cur, *pblock, level, *pbp)) {
610 		xchk_btree_set_corrupt(bs->sc, bs->cur, level);
611 		/*
612 		 * The btree block fails basic checks, so we know it's corrupt.
613 		 * There's no need to continue looking for corruptions, so we
614 		 * null out pblock.  If *pbp is non-null then it's also
615 		 * attached to the transaction so we won't leak it despite the
616 		 * 0 return code.
617 		 */
618 		*pblock = NULL;
619 		return 0;
620 	}
621 	if (*pbp)
622 		xchk_buffer_recheck(bs->sc, *pbp);
623 
624 	xchk_btree_check_minrecs(bs, level, *pblock);
625 
626 	/*
627 	 * Check the block's owner; this function absorbs error codes
628 	 * for us.
629 	 */
630 	error = xchk_btree_check_owner(bs, level, *pbp);
631 	if (error)
632 		return error;
633 
634 	/*
635 	 * Check the block's siblings; this function absorbs error codes
636 	 * for us.
637 	 */
638 	error = xchk_btree_block_check_siblings(bs, *pblock);
639 	if (error)
640 		return error;
641 
642 	xchk_btree_block_check_keys(bs, level, *pblock);
643 	return 0;
644 }
645 
646 /*
647  * Check that the low and high keys of this block match the keys stored
648  * in the parent block.
649  */
650 STATIC void
651 xchk_btree_block_keys(
652 	struct xchk_btree	*bs,
653 	int			level,
654 	struct xfs_btree_block	*block)
655 {
656 	union xfs_btree_key	block_keys;
657 	struct xfs_btree_cur	*cur = bs->cur;
658 	union xfs_btree_key	*high_bk;
659 	union xfs_btree_key	*parent_keys;
660 	union xfs_btree_key	*high_pk;
661 	struct xfs_btree_block	*parent_block;
662 	struct xfs_buf		*bp;
663 
664 	if (level >= cur->bc_nlevels - 1)
665 		return;
666 
667 	/* Calculate the keys for this block. */
668 	xfs_btree_get_keys(cur, block, &block_keys);
669 
670 	/* Obtain the parent's copy of the keys for this block. */
671 	parent_block = xfs_btree_get_block(cur, level + 1, &bp);
672 	parent_keys = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr,
673 			parent_block);
674 
675 	if (xfs_btree_keycmp_ne(cur, &block_keys, parent_keys))
676 		xchk_btree_set_corrupt(bs->sc, cur, 1);
677 
678 	if (!(cur->bc_ops->geom_flags & XFS_BTGEO_OVERLAPPING))
679 		return;
680 
681 	/* Get high keys */
682 	high_bk = xfs_btree_high_key_from_key(cur, &block_keys);
683 	high_pk = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr,
684 			parent_block);
685 
686 	if (xfs_btree_keycmp_ne(cur, high_bk, high_pk))
687 		xchk_btree_set_corrupt(bs->sc, cur, 1);
688 }
689 
690 /*
691  * Visit all nodes and leaves of a btree.  Check that all pointers and
692  * records are in order, that the keys reflect the records, and use a callback
693  * so that the caller can verify individual records.
694  */
695 int
696 xchk_btree(
697 	struct xfs_scrub		*sc,
698 	struct xfs_btree_cur		*cur,
699 	xchk_btree_rec_fn		scrub_fn,
700 	const struct xfs_owner_info	*oinfo,
701 	void				*private)
702 {
703 	union xfs_btree_ptr		ptr;
704 	struct xchk_btree		*bs;
705 	union xfs_btree_ptr		*pp;
706 	union xfs_btree_rec		*recp;
707 	struct xfs_btree_block		*block;
708 	struct xfs_buf			*bp;
709 	struct check_owner		*co;
710 	struct check_owner		*n;
711 	size_t				cur_sz;
712 	int				level;
713 	int				error = 0;
714 
715 	/*
716 	 * Allocate the btree scrub context from the heap, because this
717 	 * structure can get rather large.  Don't let a caller feed us a
718 	 * totally absurd size.
719 	 */
720 	cur_sz = xchk_btree_sizeof(cur->bc_nlevels);
721 	if (cur_sz > PAGE_SIZE) {
722 		xchk_btree_set_corrupt(sc, cur, 0);
723 		return 0;
724 	}
725 	bs = kzalloc(cur_sz, XCHK_GFP_FLAGS);
726 	if (!bs)
727 		return -ENOMEM;
728 	bs->cur = cur;
729 	bs->scrub_rec = scrub_fn;
730 	bs->oinfo = oinfo;
731 	bs->private = private;
732 	bs->sc = sc;
733 
734 	/* Initialize scrub state */
735 	INIT_LIST_HEAD(&bs->to_check);
736 
737 	/*
738 	 * Load the root of the btree.  The helper function absorbs
739 	 * error codes for us.
740 	 */
741 	level = cur->bc_nlevels - 1;
742 	xfs_btree_init_ptr_from_cur(cur, &ptr);
743 	if (!xchk_btree_ptr_ok(bs, cur->bc_nlevels, &ptr))
744 		goto out;
745 	error = xchk_btree_get_block(bs, level, &ptr, &block, &bp);
746 	if (error || !block)
747 		goto out;
748 
749 	cur->bc_levels[level].ptr = 1;
750 
751 	while (level < cur->bc_nlevels) {
752 		block = xfs_btree_get_block(cur, level, &bp);
753 
754 		if (level == 0) {
755 			/* End of leaf, pop back towards the root. */
756 			if (cur->bc_levels[level].ptr >
757 			    be16_to_cpu(block->bb_numrecs)) {
758 				xchk_btree_block_keys(bs, level, block);
759 				if (level < cur->bc_nlevels - 1)
760 					cur->bc_levels[level + 1].ptr++;
761 				level++;
762 				continue;
763 			}
764 
765 			/* Records in order for scrub? */
766 			xchk_btree_rec(bs);
767 
768 			/* Call out to the record checker. */
769 			recp = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr,
770 					block);
771 			error = bs->scrub_rec(bs, recp);
772 			if (error)
773 				break;
774 			if (xchk_should_terminate(sc, &error) ||
775 			    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
776 				break;
777 
778 			cur->bc_levels[level].ptr++;
779 			continue;
780 		}
781 
782 		/* End of node, pop back towards the root. */
783 		if (cur->bc_levels[level].ptr >
784 					be16_to_cpu(block->bb_numrecs)) {
785 			xchk_btree_block_keys(bs, level, block);
786 			if (level < cur->bc_nlevels - 1)
787 				cur->bc_levels[level + 1].ptr++;
788 			level++;
789 			continue;
790 		}
791 
792 		/* Keys in order for scrub? */
793 		xchk_btree_key(bs, level);
794 
795 		/* Drill another level deeper. */
796 		pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block);
797 		if (!xchk_btree_ptr_ok(bs, level, pp)) {
798 			cur->bc_levels[level].ptr++;
799 			continue;
800 		}
801 		level--;
802 		error = xchk_btree_get_block(bs, level, pp, &block, &bp);
803 		if (error || !block)
804 			goto out;
805 
806 		cur->bc_levels[level].ptr = 1;
807 	}
808 
809 out:
810 	/* Process deferred owner checks on btree blocks. */
811 	list_for_each_entry_safe(co, n, &bs->to_check, list) {
812 		if (!error && bs->cur)
813 			error = xchk_btree_check_block_owner(bs, co->level,
814 					co->daddr);
815 		list_del(&co->list);
816 		kfree(co);
817 	}
818 	kfree(bs);
819 
820 	return error;
821 }
822