162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
462306a36Sopenharmony_ci * Author: Darrick J. Wong <djwong@kernel.org>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_SCRUB_BTREE_H__
762306a36Sopenharmony_ci#define __XFS_SCRUB_BTREE_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/* btree scrub */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* Check for btree operation errors. */
1262306a36Sopenharmony_cibool xchk_btree_process_error(struct xfs_scrub *sc,
1362306a36Sopenharmony_ci		struct xfs_btree_cur *cur, int level, int *error);
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* Check for btree xref operation errors. */
1662306a36Sopenharmony_cibool xchk_btree_xref_process_error(struct xfs_scrub *sc,
1762306a36Sopenharmony_ci		struct xfs_btree_cur *cur, int level, int *error);
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/* Check for btree corruption. */
2062306a36Sopenharmony_civoid xchk_btree_set_corrupt(struct xfs_scrub *sc,
2162306a36Sopenharmony_ci		struct xfs_btree_cur *cur, int level);
2262306a36Sopenharmony_civoid xchk_btree_set_preen(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
2362306a36Sopenharmony_ci		int level);
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* Check for btree xref discrepancies. */
2662306a36Sopenharmony_civoid xchk_btree_xref_set_corrupt(struct xfs_scrub *sc,
2762306a36Sopenharmony_ci		struct xfs_btree_cur *cur, int level);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct xchk_btree;
3062306a36Sopenharmony_citypedef int (*xchk_btree_rec_fn)(
3162306a36Sopenharmony_ci	struct xchk_btree		*bs,
3262306a36Sopenharmony_ci	const union xfs_btree_rec	*rec);
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct xchk_btree_key {
3562306a36Sopenharmony_ci	union xfs_btree_key		key;
3662306a36Sopenharmony_ci	bool				valid;
3762306a36Sopenharmony_ci};
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistruct xchk_btree {
4062306a36Sopenharmony_ci	/* caller-provided scrub state */
4162306a36Sopenharmony_ci	struct xfs_scrub		*sc;
4262306a36Sopenharmony_ci	struct xfs_btree_cur		*cur;
4362306a36Sopenharmony_ci	xchk_btree_rec_fn		scrub_rec;
4462306a36Sopenharmony_ci	const struct xfs_owner_info	*oinfo;
4562306a36Sopenharmony_ci	void				*private;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	/* internal scrub state */
4862306a36Sopenharmony_ci	bool				lastrec_valid;
4962306a36Sopenharmony_ci	union xfs_btree_rec		lastrec;
5062306a36Sopenharmony_ci	struct list_head		to_check;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	/* this element must come last! */
5362306a36Sopenharmony_ci	struct xchk_btree_key		lastkey[];
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * Calculate the size of a xchk_btree structure.  There are nlevels-1 slots for
5862306a36Sopenharmony_ci * keys because we track leaf records separately in lastrec.
5962306a36Sopenharmony_ci */
6062306a36Sopenharmony_cistatic inline size_t
6162306a36Sopenharmony_cixchk_btree_sizeof(unsigned int nlevels)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	return struct_size_t(struct xchk_btree, lastkey, nlevels - 1);
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciint xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
6762306a36Sopenharmony_ci		xchk_btree_rec_fn scrub_fn, const struct xfs_owner_info *oinfo,
6862306a36Sopenharmony_ci		void *private);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#endif /* __XFS_SCRUB_BTREE_H__ */
71