aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/persistent-data/dm-btree.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2013-03-01 17:45:50 -0500
committerAlasdair G Kergon <agk@redhat.com>2013-03-01 17:45:50 -0500
commit4e7f1f9089660aec3b5ab2645ce62777c6f4c6a2 (patch)
tree56f012273947dcd88e4a73944aae37d01f023b56 /drivers/md/persistent-data/dm-btree.c
parentb0d8ed4d96a26ef3ac54a4aa8911c9413070662e (diff)
dm persistent data: add btree_walk
Add dm_btree_walk to iterate through the contents of a btree. This will be used by the dm cache target. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/persistent-data/dm-btree.c')
-rw-r--r--drivers/md/persistent-data/dm-btree.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index 4caf66918cdb..35865425e4b4 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -807,3 +807,55 @@ int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
807 return r ? r : count; 807 return r ? r : count;
808} 808}
809EXPORT_SYMBOL_GPL(dm_btree_find_highest_key); 809EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
810
811/*
812 * FIXME: We shouldn't use a recursive algorithm when we have limited stack
813 * space. Also this only works for single level trees.
814 */
815static int walk_node(struct ro_spine *s, dm_block_t block,
816 int (*fn)(void *context, uint64_t *keys, void *leaf),
817 void *context)
818{
819 int r;
820 unsigned i, nr;
821 struct btree_node *n;
822 uint64_t keys;
823
824 r = ro_step(s, block);
825 n = ro_node(s);
826
827 nr = le32_to_cpu(n->header.nr_entries);
828 for (i = 0; i < nr; i++) {
829 if (le32_to_cpu(n->header.flags) & INTERNAL_NODE) {
830 r = walk_node(s, value64(n, i), fn, context);
831 if (r)
832 goto out;
833 } else {
834 keys = le64_to_cpu(*key_ptr(n, i));
835 r = fn(context, &keys, value_ptr(n, i));
836 if (r)
837 goto out;
838 }
839 }
840
841out:
842 ro_pop(s);
843 return r;
844}
845
846int dm_btree_walk(struct dm_btree_info *info, dm_block_t root,
847 int (*fn)(void *context, uint64_t *keys, void *leaf),
848 void *context)
849{
850 int r;
851 struct ro_spine spine;
852
853 BUG_ON(info->levels > 1);
854
855 init_ro_spine(&spine, info);
856 r = walk_node(&spine, root, fn, context);
857 exit_ro_spine(&spine);
858
859 return r;
860}
861EXPORT_SYMBOL_GPL(dm_btree_walk);