summaryrefslogtreecommitdiffstats
path: root/drivers/md/persistent-data/dm-bitset.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2016-10-05 16:40:39 +0200
committerMike Snitzer <snitzer@redhat.com>2017-02-16 19:12:50 +0100
commit9b696229aa7de356675a938c6c8a70b46085ed66 (patch)
tree19ab9da696f91ed4987a091854d8a8cd8dd6a5bb /drivers/md/persistent-data/dm-bitset.c
parentdm cache metadata: use dm_bitset_new() to create the dirty bitset in format 2 (diff)
downloadlinux-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.c35
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);