summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/scrub/bitmap.c')
-rw-r--r--fs/xfs/scrub/bitmap.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c
index 8b704d7b5855..1041f17f6bb6 100644
--- a/fs/xfs/scrub/bitmap.c
+++ b/fs/xfs/scrub/bitmap.c
@@ -12,6 +12,9 @@
#include "xfs_btree.h"
#include "scrub/bitmap.h"
+#define for_each_xbitmap_extent(bex, n, bitmap) \
+ list_for_each_entry_safe((bex), (n), &(bitmap)->list, list)
+
/*
* Set a range of this bitmap. Caller must ensure the range is not set.
*
@@ -311,3 +314,59 @@ xbitmap_hweight(
return ret;
}
+
+/* Call a function for every run of set bits in this bitmap. */
+int
+xbitmap_iter_set(
+ struct xbitmap *bitmap,
+ xbitmap_walk_run_fn fn,
+ void *priv)
+{
+ struct xbitmap_range *bex, *n;
+ int error;
+
+ for_each_xbitmap_extent(bex, n, bitmap) {
+ error = fn(bex->start, bex->len, priv);
+ if (error)
+ break;
+ }
+
+ return error;
+}
+
+struct xbitmap_walk_bits {
+ xbitmap_walk_bit_fn fn;
+ void *priv;
+};
+
+/* Walk all the bits in a run. */
+static int
+xbitmap_walk_bits_in_run(
+ uint64_t start,
+ uint64_t len,
+ void *priv)
+{
+ struct xbitmap_walk_bits *wb = priv;
+ uint64_t i;
+ int error;
+
+ for (i = start; i < start + len; i++) {
+ error = wb->fn(i, wb->priv);
+ if (error)
+ break;
+ }
+
+ return error;
+}
+
+/* Call a function for every set bit in this bitmap. */
+int
+xbitmap_iter_set_bits(
+ struct xbitmap *bitmap,
+ xbitmap_walk_bit_fn fn,
+ void *priv)
+{
+ struct xbitmap_walk_bits wb = {.fn = fn, .priv = priv};
+
+ return xbitmap_iter_set(bitmap, xbitmap_walk_bits_in_run, &wb);
+}