162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2018-2023 Oracle.  All Rights Reserved.
462306a36Sopenharmony_ci * Author: Darrick J. Wong <djwong@kernel.org>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef __XFS_SCRUB_BITMAP_H__
762306a36Sopenharmony_ci#define __XFS_SCRUB_BITMAP_H__
862306a36Sopenharmony_ci
962306a36Sopenharmony_cistruct xbitmap {
1062306a36Sopenharmony_ci	struct rb_root_cached	xb_root;
1162306a36Sopenharmony_ci};
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_civoid xbitmap_init(struct xbitmap *bitmap);
1462306a36Sopenharmony_civoid xbitmap_destroy(struct xbitmap *bitmap);
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciint xbitmap_clear(struct xbitmap *bitmap, uint64_t start, uint64_t len);
1762306a36Sopenharmony_ciint xbitmap_set(struct xbitmap *bitmap, uint64_t start, uint64_t len);
1862306a36Sopenharmony_ciint xbitmap_disunion(struct xbitmap *bitmap, struct xbitmap *sub);
1962306a36Sopenharmony_ciuint64_t xbitmap_hweight(struct xbitmap *bitmap);
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * Return codes for the bitmap iterator functions are 0 to continue iterating,
2362306a36Sopenharmony_ci * and non-zero to stop iterating.  Any non-zero value will be passed up to the
2462306a36Sopenharmony_ci * iteration caller.  The special value -ECANCELED can be used to stop
2562306a36Sopenharmony_ci * iteration, because neither bitmap iterator ever generates that error code on
2662306a36Sopenharmony_ci * its own.  Callers must not modify the bitmap while walking it.
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_citypedef int (*xbitmap_walk_fn)(uint64_t start, uint64_t len, void *priv);
2962306a36Sopenharmony_ciint xbitmap_walk(struct xbitmap *bitmap, xbitmap_walk_fn fn,
3062306a36Sopenharmony_ci		void *priv);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cibool xbitmap_empty(struct xbitmap *bitmap);
3362306a36Sopenharmony_cibool xbitmap_test(struct xbitmap *bitmap, uint64_t start, uint64_t *len);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* Bitmaps, but for type-checked for xfs_agblock_t */
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistruct xagb_bitmap {
3862306a36Sopenharmony_ci	struct xbitmap	agbitmap;
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cistatic inline void xagb_bitmap_init(struct xagb_bitmap *bitmap)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	xbitmap_init(&bitmap->agbitmap);
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic inline void xagb_bitmap_destroy(struct xagb_bitmap *bitmap)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	xbitmap_destroy(&bitmap->agbitmap);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic inline int xagb_bitmap_clear(struct xagb_bitmap *bitmap,
5262306a36Sopenharmony_ci		xfs_agblock_t start, xfs_extlen_t len)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	return xbitmap_clear(&bitmap->agbitmap, start, len);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_cistatic inline int xagb_bitmap_set(struct xagb_bitmap *bitmap,
5762306a36Sopenharmony_ci		xfs_agblock_t start, xfs_extlen_t len)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return xbitmap_set(&bitmap->agbitmap, start, len);
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic inline bool
6362306a36Sopenharmony_cixagb_bitmap_test(
6462306a36Sopenharmony_ci	struct xagb_bitmap	*bitmap,
6562306a36Sopenharmony_ci	xfs_agblock_t		start,
6662306a36Sopenharmony_ci	xfs_extlen_t		*len)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	uint64_t		biglen = *len;
6962306a36Sopenharmony_ci	bool			ret;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	ret = xbitmap_test(&bitmap->agbitmap, start, &biglen);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	if (start + biglen >= UINT_MAX) {
7462306a36Sopenharmony_ci		ASSERT(0);
7562306a36Sopenharmony_ci		biglen = UINT_MAX - start;
7662306a36Sopenharmony_ci	}
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	*len = biglen;
7962306a36Sopenharmony_ci	return ret;
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic inline int xagb_bitmap_disunion(struct xagb_bitmap *bitmap,
8362306a36Sopenharmony_ci		struct xagb_bitmap *sub)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	return xbitmap_disunion(&bitmap->agbitmap, &sub->agbitmap);
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic inline uint32_t xagb_bitmap_hweight(struct xagb_bitmap *bitmap)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	return xbitmap_hweight(&bitmap->agbitmap);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_cistatic inline bool xagb_bitmap_empty(struct xagb_bitmap *bitmap)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	return xbitmap_empty(&bitmap->agbitmap);
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic inline int xagb_bitmap_walk(struct xagb_bitmap *bitmap,
9862306a36Sopenharmony_ci		xbitmap_walk_fn fn, void *priv)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	return xbitmap_walk(&bitmap->agbitmap, fn, priv);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciint xagb_bitmap_set_btblocks(struct xagb_bitmap *bitmap,
10462306a36Sopenharmony_ci		struct xfs_btree_cur *cur);
10562306a36Sopenharmony_ciint xagb_bitmap_set_btcur_path(struct xagb_bitmap *bitmap,
10662306a36Sopenharmony_ci		struct xfs_btree_cur *cur);
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#endif	/* __XFS_SCRUB_BITMAP_H__ */
109