diff options
author | Joe Thornber <ejt@redhat.com> | 2016-09-15 11:11:42 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-09-22 11:15:04 -0400 |
commit | fdd1315aa5f022fe6574efdc2d9535f75a0ee255 (patch) | |
tree | 769113eca5f6a1594247d62410dbd829e74d8fd3 /drivers/md/persistent-data/dm-array.c | |
parent | 7d111c81fa29041c730010450618917fb05cab62 (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.c | 86 |
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, | |||
899 | EXPORT_SYMBOL_GPL(dm_array_walk); | 899 | EXPORT_SYMBOL_GPL(dm_array_walk); |
900 | 900 | ||
901 | /*----------------------------------------------------------------*/ | 901 | /*----------------------------------------------------------------*/ |
902 | |||
903 | static 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 | |||
932 | int 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 | } | ||
947 | EXPORT_SYMBOL_GPL(dm_array_cursor_begin); | ||
948 | |||
949 | void 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 | } | ||
956 | EXPORT_SYMBOL_GPL(dm_array_cursor_end); | ||
957 | |||
958 | int 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 | } | ||
979 | EXPORT_SYMBOL_GPL(dm_array_cursor_next); | ||
980 | |||
981 | void 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 | } | ||
985 | EXPORT_SYMBOL_GPL(dm_array_cursor_get_value); | ||
986 | |||
987 | /*----------------------------------------------------------------*/ | ||