diff options
Diffstat (limited to 'fs/xfs/scrub/bitmap.c')
-rw-r--r-- | fs/xfs/scrub/bitmap.c | 59 |
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); +} |