1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2018-2023 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
5 */
6 #ifndef __XFS_SCRUB_BITMAP_H__
7 #define __XFS_SCRUB_BITMAP_H__
8
9 struct xbitmap {
10 struct rb_root_cached xb_root;
11 };
12
13 void xbitmap_init(struct xbitmap *bitmap);
14 void xbitmap_destroy(struct xbitmap *bitmap);
15
16 int xbitmap_clear(struct xbitmap *bitmap, uint64_t start, uint64_t len);
17 int xbitmap_set(struct xbitmap *bitmap, uint64_t start, uint64_t len);
18 int xbitmap_disunion(struct xbitmap *bitmap, struct xbitmap *sub);
19 uint64_t xbitmap_hweight(struct xbitmap *bitmap);
20
21 /*
22 * Return codes for the bitmap iterator functions are 0 to continue iterating,
23 * and non-zero to stop iterating. Any non-zero value will be passed up to the
24 * iteration caller. The special value -ECANCELED can be used to stop
25 * iteration, because neither bitmap iterator ever generates that error code on
26 * its own. Callers must not modify the bitmap while walking it.
27 */
28 typedef int (*xbitmap_walk_fn)(uint64_t start, uint64_t len, void *priv);
29 int xbitmap_walk(struct xbitmap *bitmap, xbitmap_walk_fn fn,
30 void *priv);
31
32 bool xbitmap_empty(struct xbitmap *bitmap);
33 bool xbitmap_test(struct xbitmap *bitmap, uint64_t start, uint64_t *len);
34
35 /* Bitmaps, but for type-checked for xfs_agblock_t */
36
37 struct xagb_bitmap {
38 struct xbitmap agbitmap;
39 };
40
xagb_bitmap_init(struct xagb_bitmap * bitmap)41 static inline void xagb_bitmap_init(struct xagb_bitmap *bitmap)
42 {
43 xbitmap_init(&bitmap->agbitmap);
44 }
45
xagb_bitmap_destroy(struct xagb_bitmap * bitmap)46 static inline void xagb_bitmap_destroy(struct xagb_bitmap *bitmap)
47 {
48 xbitmap_destroy(&bitmap->agbitmap);
49 }
50
xagb_bitmap_clear(struct xagb_bitmap * bitmap,xfs_agblock_t start,xfs_extlen_t len)51 static inline int xagb_bitmap_clear(struct xagb_bitmap *bitmap,
52 xfs_agblock_t start, xfs_extlen_t len)
53 {
54 return xbitmap_clear(&bitmap->agbitmap, start, len);
55 }
xagb_bitmap_set(struct xagb_bitmap * bitmap,xfs_agblock_t start,xfs_extlen_t len)56 static inline int xagb_bitmap_set(struct xagb_bitmap *bitmap,
57 xfs_agblock_t start, xfs_extlen_t len)
58 {
59 return xbitmap_set(&bitmap->agbitmap, start, len);
60 }
61
62 static inline bool
xagb_bitmap_test(struct xagb_bitmap * bitmap,xfs_agblock_t start,xfs_extlen_t * len)63 xagb_bitmap_test(
64 struct xagb_bitmap *bitmap,
65 xfs_agblock_t start,
66 xfs_extlen_t *len)
67 {
68 uint64_t biglen = *len;
69 bool ret;
70
71 ret = xbitmap_test(&bitmap->agbitmap, start, &biglen);
72
73 if (start + biglen >= UINT_MAX) {
74 ASSERT(0);
75 biglen = UINT_MAX - start;
76 }
77
78 *len = biglen;
79 return ret;
80 }
81
xagb_bitmap_disunion(struct xagb_bitmap * bitmap,struct xagb_bitmap * sub)82 static inline int xagb_bitmap_disunion(struct xagb_bitmap *bitmap,
83 struct xagb_bitmap *sub)
84 {
85 return xbitmap_disunion(&bitmap->agbitmap, &sub->agbitmap);
86 }
87
xagb_bitmap_hweight(struct xagb_bitmap * bitmap)88 static inline uint32_t xagb_bitmap_hweight(struct xagb_bitmap *bitmap)
89 {
90 return xbitmap_hweight(&bitmap->agbitmap);
91 }
xagb_bitmap_empty(struct xagb_bitmap * bitmap)92 static inline bool xagb_bitmap_empty(struct xagb_bitmap *bitmap)
93 {
94 return xbitmap_empty(&bitmap->agbitmap);
95 }
96
xagb_bitmap_walk(struct xagb_bitmap * bitmap,xbitmap_walk_fn fn,void * priv)97 static inline int xagb_bitmap_walk(struct xagb_bitmap *bitmap,
98 xbitmap_walk_fn fn, void *priv)
99 {
100 return xbitmap_walk(&bitmap->agbitmap, fn, priv);
101 }
102
103 int xagb_bitmap_set_btblocks(struct xagb_bitmap *bitmap,
104 struct xfs_btree_cur *cur);
105 int xagb_bitmap_set_btcur_path(struct xagb_bitmap *bitmap,
106 struct xfs_btree_cur *cur);
107
108 #endif /* __XFS_SCRUB_BITMAP_H__ */
109