Commit f164e690 authored by Joe Thornber's avatar Joe Thornber Committed by Mike Snitzer

dm btree: add dm_btree_find_lowest_key

dm_btree_find_lowest_key is the reciprocal of dm_btree_find_highest_key.
Factor out common code for dm_btree_find_{highest,lowest}_key.

dm_btree_find_lowest_key is needed for an upcoming DM target, as such it
is best to get this interface in place.
Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 7e664b3d
...@@ -770,8 +770,8 @@ EXPORT_SYMBOL_GPL(dm_btree_insert_notify); ...@@ -770,8 +770,8 @@ EXPORT_SYMBOL_GPL(dm_btree_insert_notify);
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
static int find_highest_key(struct ro_spine *s, dm_block_t block, static int find_key(struct ro_spine *s, dm_block_t block, bool find_highest,
uint64_t *result_key, dm_block_t *next_block) uint64_t *result_key, dm_block_t *next_block)
{ {
int i, r; int i, r;
uint32_t flags; uint32_t flags;
...@@ -788,7 +788,11 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block, ...@@ -788,7 +788,11 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block,
else else
i--; i--;
*result_key = le64_to_cpu(ro_node(s)->keys[i]); if (find_highest)
*result_key = le64_to_cpu(ro_node(s)->keys[i]);
else
*result_key = le64_to_cpu(ro_node(s)->keys[0]);
if (next_block || flags & INTERNAL_NODE) if (next_block || flags & INTERNAL_NODE)
block = value64(ro_node(s), i); block = value64(ro_node(s), i);
...@@ -799,16 +803,16 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block, ...@@ -799,16 +803,16 @@ static int find_highest_key(struct ro_spine *s, dm_block_t block,
return 0; return 0;
} }
int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root, static int dm_btree_find_key(struct dm_btree_info *info, dm_block_t root,
uint64_t *result_keys) bool find_highest, uint64_t *result_keys)
{ {
int r = 0, count = 0, level; int r = 0, count = 0, level;
struct ro_spine spine; struct ro_spine spine;
init_ro_spine(&spine, info); init_ro_spine(&spine, info);
for (level = 0; level < info->levels; level++) { for (level = 0; level < info->levels; level++) {
r = find_highest_key(&spine, root, result_keys + level, r = find_key(&spine, root, find_highest, result_keys + level,
level == info->levels - 1 ? NULL : &root); level == info->levels - 1 ? NULL : &root);
if (r == -ENODATA) { if (r == -ENODATA) {
r = 0; r = 0;
break; break;
...@@ -822,8 +826,23 @@ int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root, ...@@ -822,8 +826,23 @@ int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
return r ? r : count; return r ? r : count;
} }
int dm_btree_find_highest_key(struct dm_btree_info *info, dm_block_t root,
uint64_t *result_keys)
{
return dm_btree_find_key(info, root, true, result_keys);
}
EXPORT_SYMBOL_GPL(dm_btree_find_highest_key); EXPORT_SYMBOL_GPL(dm_btree_find_highest_key);
int dm_btree_find_lowest_key(struct dm_btree_info *info, dm_block_t root,
uint64_t *result_keys)
{
return dm_btree_find_key(info, root, false, result_keys);
}
EXPORT_SYMBOL_GPL(dm_btree_find_lowest_key);
/*----------------------------------------------------------------*/
/* /*
* FIXME: We shouldn't use a recursive algorithm when we have limited stack * FIXME: We shouldn't use a recursive algorithm when we have limited stack
* space. Also this only works for single level trees. * space. Also this only works for single level trees.
......
...@@ -134,6 +134,14 @@ int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root, ...@@ -134,6 +134,14 @@ int dm_btree_insert_notify(struct dm_btree_info *info, dm_block_t root,
int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
uint64_t *keys, dm_block_t *new_root); uint64_t *keys, dm_block_t *new_root);
/*
* Returns < 0 on failure. Otherwise the number of key entries that have
* been filled out. Remember trees can have zero entries, and as such have
* no lowest key.
*/
int dm_btree_find_lowest_key(struct dm_btree_info *info, dm_block_t root,
uint64_t *result_keys);
/* /*
* Returns < 0 on failure. Otherwise the number of key entries that have * Returns < 0 on failure. Otherwise the number of key entries that have
* been filled out. Remember trees can have zero entries, and as such have * been filled out. Remember trees can have zero entries, and as such have
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment