dm bitset: introduce cursor api
authorJoe Thornber <ejt@redhat.com>
Mon, 3 Oct 2016 18:15:02 +0000 (14:15 -0400)
committerMike Snitzer <snitzer@redhat.com>
Thu, 16 Feb 2017 18:12:45 +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-bitset.c
drivers/md/persistent-data/dm-bitset.h

index 36f7cc2c7109b45b77a1ff27e1f7b1a146dbfcf1..7cb28516cc19675e5833825e0cdceb27ea54786e 100644 (file)
@@ -168,4 +168,73 @@ int dm_bitset_test_bit(struct dm_disk_bitset *info, dm_block_t root,
 }
 EXPORT_SYMBOL_GPL(dm_bitset_test_bit);
 
+static int cursor_next_array_entry(struct dm_bitset_cursor *c)
+{
+       int r;
+       __le64 *value;
+
+       r = dm_array_cursor_next(&c->cursor);
+       if (r)
+               return r;
+
+       dm_array_cursor_get_value(&c->cursor, (void **) &value);
+       c->array_index++;
+       c->bit_index = 0;
+       c->current_bits = le64_to_cpu(*value);
+       return 0;
+}
+
+int dm_bitset_cursor_begin(struct dm_disk_bitset *info,
+                          dm_block_t root, uint32_t nr_entries,
+                          struct dm_bitset_cursor *c)
+{
+       int r;
+       __le64 *value;
+
+       if (!nr_entries)
+               return -ENODATA;
+
+       c->info = info;
+       c->entries_remaining = nr_entries;
+
+       r = dm_array_cursor_begin(&info->array_info, root, &c->cursor);
+       if (r)
+               return r;
+
+       dm_array_cursor_get_value(&c->cursor, (void **) &value);
+       c->array_index = 0;
+       c->bit_index = 0;
+       c->current_bits = le64_to_cpu(*value);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_bitset_cursor_begin);
+
+void dm_bitset_cursor_end(struct dm_bitset_cursor *c)
+{
+       return dm_array_cursor_end(&c->cursor);
+}
+EXPORT_SYMBOL_GPL(dm_bitset_cursor_end);
+
+int dm_bitset_cursor_next(struct dm_bitset_cursor *c)
+{
+       int r = 0;
+
+       if (!c->entries_remaining)
+               return -ENODATA;
+
+       c->entries_remaining--;
+       if (++c->bit_index > 63)
+               r = cursor_next_array_entry(c);
+
+       return r;
+}
+EXPORT_SYMBOL_GPL(dm_bitset_cursor_next);
+
+bool dm_bitset_cursor_get_value(struct dm_bitset_cursor *c)
+{
+       return test_bit(c->bit_index, (unsigned long *) &c->current_bits);
+}
+EXPORT_SYMBOL_GPL(dm_bitset_cursor_get_value);
+
 /*----------------------------------------------------------------*/
index c2287d672ef5ed4735b91fe9fac3f708c9b7df64..017c0d42cdbf369d68b1db9100a118a905a2f8d0 100644 (file)
@@ -161,6 +161,28 @@ int dm_bitset_test_bit(struct dm_disk_bitset *info, dm_block_t root,
 int dm_bitset_flush(struct dm_disk_bitset *info, dm_block_t root,
                    dm_block_t *new_root);
 
+struct dm_bitset_cursor {
+       struct dm_disk_bitset *info;
+       struct dm_array_cursor cursor;
+
+       uint32_t entries_remaining;
+       uint32_t array_index;
+       uint32_t bit_index;
+       uint64_t current_bits;
+};
+
+/*
+ * Make sure you've flush any dm_disk_bitset and updated the root before
+ * using this.
+ */
+int dm_bitset_cursor_begin(struct dm_disk_bitset *info,
+                          dm_block_t root, uint32_t nr_entries,
+                          struct dm_bitset_cursor *c);
+void dm_bitset_cursor_end(struct dm_bitset_cursor *c);
+
+int dm_bitset_cursor_next(struct dm_bitset_cursor *c);
+bool dm_bitset_cursor_get_value(struct dm_bitset_cursor *c);
+
 /*----------------------------------------------------------------*/
 
 #endif /* _LINUX_DM_BITSET_H */