diff options
author | Joe Thornber <ejt@redhat.com> | 2016-10-05 16:40:39 +0200 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2017-02-16 19:12:50 +0100 |
commit | 9b696229aa7de356675a938c6c8a70b46085ed66 (patch) | |
tree | 19ab9da696f91ed4987a091854d8a8cd8dd6a5bb /drivers/md/persistent-data/dm-bitset.c | |
parent | dm cache metadata: use dm_bitset_new() to create the dirty bitset in format 2 (diff) | |
download | linux-9b696229aa7de356675a938c6c8a70b46085ed66.tar.xz linux-9b696229aa7de356675a938c6c8a70b46085ed66.zip |
dm persistent data: add cursor skip functions to the cursor APIs
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/persistent-data/dm-bitset.c')
-rw-r--r-- | drivers/md/persistent-data/dm-bitset.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/md/persistent-data/dm-bitset.c b/drivers/md/persistent-data/dm-bitset.c index fbf8d9bc4d15..b7208d82e748 100644 --- a/drivers/md/persistent-data/dm-bitset.c +++ b/drivers/md/persistent-data/dm-bitset.c @@ -273,6 +273,41 @@ int dm_bitset_cursor_next(struct dm_bitset_cursor *c) } EXPORT_SYMBOL_GPL(dm_bitset_cursor_next); +int dm_bitset_cursor_skip(struct dm_bitset_cursor *c, uint32_t count) +{ + int r; + __le64 *value; + uint32_t nr_array_skip; + uint32_t remaining_in_word = 64 - c->bit_index; + + if (c->entries_remaining < count) + return -ENODATA; + + if (count < remaining_in_word) { + c->bit_index += count; + c->entries_remaining -= count; + return 0; + + } else { + c->entries_remaining -= remaining_in_word; + count -= remaining_in_word; + } + + nr_array_skip = (count / 64) + 1; + r = dm_array_cursor_skip(&c->cursor, nr_array_skip); + if (r) + return r; + + dm_array_cursor_get_value(&c->cursor, (void **) &value); + c->entries_remaining -= count; + c->array_index += nr_array_skip; + c->bit_index = count & 63; + c->current_bits = le64_to_cpu(*value); + + return 0; +} +EXPORT_SYMBOL_GPL(dm_bitset_cursor_skip); + bool dm_bitset_cursor_get_value(struct dm_bitset_cursor *c) { return test_bit(c->bit_index, (unsigned long *) &c->current_bits); |