dm persistent data: add cursor skip functions to the cursor APIs
authorJoe Thornber <ejt@redhat.com>
Wed, 5 Oct 2016 14:40:39 +0000 (10:40 -0400)
committerMike Snitzer <snitzer@redhat.com>
Thu, 16 Feb 2017 18:12:50 +0000 (13:12 -0500)
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/persistent-data/dm-array.c
drivers/md/persistent-data/dm-array.h
drivers/md/persistent-data/dm-bitset.c
drivers/md/persistent-data/dm-bitset.h
drivers/md/persistent-data/dm-btree.c
drivers/md/persistent-data/dm-btree.h

index 7938cd2..185dc60 100644 (file)
@@ -976,6 +976,27 @@ int dm_array_cursor_next(struct dm_array_cursor *c)
 }
 EXPORT_SYMBOL_GPL(dm_array_cursor_next);
 
+int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
+{
+       int r;
+
+       do {
+               uint32_t remaining = le32_to_cpu(c->ab->nr_entries) - c->index;
+
+               if (count < remaining) {
+                       c->index += count;
+                       return 0;
+               }
+
+               count -= remaining;
+               r = dm_array_cursor_next(c);
+
+       } while (!r);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_array_cursor_skip);
+
 void dm_array_cursor_get_value(struct dm_array_cursor *c, void **value_le)
 {
        *value_le = element_at(c->info, c->ab, c->index);
index 27ee49a..d7d2d57 100644 (file)
@@ -207,6 +207,7 @@ void dm_array_cursor_end(struct dm_array_cursor *c);
 
 uint32_t dm_array_cursor_index(struct dm_array_cursor *c);
 int dm_array_cursor_next(struct dm_array_cursor *c);
+int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count);
 
 /*
  * value_le is only valid while the cursor points at the current value.
index fbf8d9b..b7208d8 100644 (file)
@@ -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);
index a086368..df888da 100644 (file)
@@ -197,6 +197,7 @@ int dm_bitset_cursor_begin(struct dm_disk_bitset *info,
 void dm_bitset_cursor_end(struct dm_bitset_cursor *c);
 
 int dm_bitset_cursor_next(struct dm_bitset_cursor *c);
+int dm_bitset_cursor_skip(struct dm_bitset_cursor *c, uint32_t count);
 bool dm_bitset_cursor_get_value(struct dm_bitset_cursor *c);
 
 /*----------------------------------------------------------------*/
index 1744f36..02e2ee0 100644 (file)
@@ -1144,6 +1144,17 @@ int dm_btree_cursor_next(struct dm_btree_cursor *c)
 }
 EXPORT_SYMBOL_GPL(dm_btree_cursor_next);
 
+int dm_btree_cursor_skip(struct dm_btree_cursor *c, uint32_t count)
+{
+       int r = 0;
+
+       while (count-- && !r)
+               r = dm_btree_cursor_next(c);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_btree_cursor_skip);
+
 int dm_btree_cursor_get_value(struct dm_btree_cursor *c, uint64_t *key, void *value_le)
 {
        if (c->depth) {
index db9bd26..3dc5bb1 100644 (file)
@@ -209,6 +209,7 @@ int dm_btree_cursor_begin(struct dm_btree_info *info, dm_block_t root,
                          bool prefetch_leaves, struct dm_btree_cursor *c);
 void dm_btree_cursor_end(struct dm_btree_cursor *c);
 int dm_btree_cursor_next(struct dm_btree_cursor *c);
+int dm_btree_cursor_skip(struct dm_btree_cursor *c, uint32_t count);
 int dm_btree_cursor_get_value(struct dm_btree_cursor *c, uint64_t *key, void *value_le);
 
 #endif /* _LINUX_DM_BTREE_H */