aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/persistent-data/dm-array.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2016-09-15 11:11:42 -0400
committerMike Snitzer <snitzer@redhat.com>2016-09-22 11:15:04 -0400
commitfdd1315aa5f022fe6574efdc2d9535f75a0ee255 (patch)
tree769113eca5f6a1594247d62410dbd829e74d8fd3 /drivers/md/persistent-data/dm-array.c
parent7d111c81fa29041c730010450618917fb05cab62 (diff)
dm array: introduce cursor api
More efficient way to iterate an array due to prefetching (makes use of the new dm_btree_cursor_* api). Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/persistent-data/dm-array.c')
-rw-r--r--drivers/md/persistent-data/dm-array.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/md/persistent-data/dm-array.c b/drivers/md/persistent-data/dm-array.c
index 155180954cdf..e83047cbb2da 100644
--- a/drivers/md/persistent-data/dm-array.c
+++ b/drivers/md/persistent-data/dm-array.c
@@ -899,3 +899,89 @@ int dm_array_walk(struct dm_array_info *info, dm_block_t root,
899EXPORT_SYMBOL_GPL(dm_array_walk); 899EXPORT_SYMBOL_GPL(dm_array_walk);
900 900
901/*----------------------------------------------------------------*/ 901/*----------------------------------------------------------------*/
902
903static int load_ablock(struct dm_array_cursor *c)
904{
905 int r;
906 __le64 value_le;
907 uint64_t key;
908
909 if (c->block)
910 unlock_ablock(c->info, c->block);
911
912 c->block = NULL;
913 c->ab = NULL;
914 c->index = 0;
915
916 r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
917 if (r) {
918 DMERR("dm_btree_cursor_get_value failed");
919 dm_btree_cursor_end(&c->cursor);
920
921 } else {
922 r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
923 if (r) {
924 DMERR("get_ablock failed");
925 dm_btree_cursor_end(&c->cursor);
926 }
927 }
928
929 return r;
930}
931
932int dm_array_cursor_begin(struct dm_array_info *info, dm_block_t root,
933 struct dm_array_cursor *c)
934{
935 int r;
936
937 memset(c, 0, sizeof(*c));
938 c->info = info;
939 r = dm_btree_cursor_begin(&info->btree_info, root, true, &c->cursor);
940 if (r) {
941 DMERR("couldn't create btree cursor");
942 return r;
943 }
944
945 return load_ablock(c);
946}
947EXPORT_SYMBOL_GPL(dm_array_cursor_begin);
948
949void dm_array_cursor_end(struct dm_array_cursor *c)
950{
951 if (c->block) {
952 unlock_ablock(c->info, c->block);
953 dm_btree_cursor_end(&c->cursor);
954 }
955}
956EXPORT_SYMBOL_GPL(dm_array_cursor_end);
957
958int dm_array_cursor_next(struct dm_array_cursor *c)
959{
960 int r;
961
962 if (!c->block)
963 return -ENODATA;
964
965 c->index++;
966
967 if (c->index >= le32_to_cpu(c->ab->nr_entries)) {
968 r = dm_btree_cursor_next(&c->cursor);
969 if (r)
970 return r;
971
972 r = load_ablock(c);
973 if (r)
974 return r;
975 }
976
977 return 0;
978}
979EXPORT_SYMBOL_GPL(dm_array_cursor_next);
980
981void dm_array_cursor_get_value(struct dm_array_cursor *c, void **value_le)
982{
983 *value_le = element_at(c->info, c->ab, c->index);
984}
985EXPORT_SYMBOL_GPL(dm_array_cursor_get_value);
986
987/*----------------------------------------------------------------*/