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

dm space map: optimise sm_ll_dec and sm_ll_inc

Prior to this patch these methods did a lookup followed by an insert.
Instead they now call a common mutate function that adjusts the value
according to a callback function.  This avoids traversing the data
structures twice and hence improves performance.

Also factor out sm_ll_lookup_big_ref_count() for use by both
sm_ll_lookup() and sm_ll_mutate().
Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 04f17c80
...@@ -292,16 +292,11 @@ int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result) ...@@ -292,16 +292,11 @@ int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result)
return dm_tm_unlock(ll->tm, blk); return dm_tm_unlock(ll->tm, blk);
} }
int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result) static int sm_ll_lookup_big_ref_count(struct ll_disk *ll, dm_block_t b,
uint32_t *result)
{ {
__le32 le_rc; __le32 le_rc;
int r = sm_ll_lookup_bitmap(ll, b, result); int r;
if (r)
return r;
if (*result != 3)
return r;
r = dm_btree_lookup(&ll->ref_count_info, ll->ref_count_root, &b, &le_rc); r = dm_btree_lookup(&ll->ref_count_info, ll->ref_count_root, &b, &le_rc);
if (r < 0) if (r < 0)
...@@ -312,6 +307,19 @@ int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result) ...@@ -312,6 +307,19 @@ int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result)
return r; return r;
} }
int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result)
{
int r = sm_ll_lookup_bitmap(ll, b, result);
if (r)
return r;
if (*result != 3)
return r;
return sm_ll_lookup_big_ref_count(ll, b, result);
}
int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
dm_block_t end, dm_block_t *result) dm_block_t end, dm_block_t *result)
{ {
...@@ -372,11 +380,12 @@ int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, ...@@ -372,11 +380,12 @@ int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin,
return -ENOSPC; return -ENOSPC;
} }
int sm_ll_insert(struct ll_disk *ll, dm_block_t b, static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b,
uint32_t ref_count, enum allocation_event *ev) uint32_t (*mutator)(void *context, uint32_t old),
void *context, enum allocation_event *ev)
{ {
int r; int r;
uint32_t bit, old; uint32_t bit, old, ref_count;
struct dm_block *nb; struct dm_block *nb;
dm_block_t index = b; dm_block_t index = b;
struct disk_index_entry ie_disk; struct disk_index_entry ie_disk;
...@@ -399,6 +408,14 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b, ...@@ -399,6 +408,14 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
bm_le = dm_bitmap_data(nb); bm_le = dm_bitmap_data(nb);
old = sm_lookup_bitmap(bm_le, bit); old = sm_lookup_bitmap(bm_le, bit);
if (old > 2) {
r = sm_ll_lookup_big_ref_count(ll, b, &old);
if (r < 0)
return r;
}
ref_count = mutator(context, old);
if (ref_count <= 2) { if (ref_count <= 2) {
sm_set_bitmap(bm_le, bit, ref_count); sm_set_bitmap(bm_le, bit, ref_count);
...@@ -448,31 +465,35 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b, ...@@ -448,31 +465,35 @@ int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
return ll->save_ie(ll, index, &ie_disk); return ll->save_ie(ll, index, &ie_disk);
} }
int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) static uint32_t set_ref_count(void *context, uint32_t old)
{ {
int r; return *((uint32_t *) context);
uint32_t rc; }
r = sm_ll_lookup(ll, b, &rc);
if (r)
return r;
return sm_ll_insert(ll, b, rc + 1, ev); int sm_ll_insert(struct ll_disk *ll, dm_block_t b,
uint32_t ref_count, enum allocation_event *ev)
{
return sm_ll_mutate(ll, b, set_ref_count, &ref_count, ev);
} }
int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) static uint32_t inc_ref_count(void *context, uint32_t old)
{ {
int r; return old + 1;
uint32_t rc; }
r = sm_ll_lookup(ll, b, &rc); int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
if (r) {
return r; return sm_ll_mutate(ll, b, inc_ref_count, NULL, ev);
}
if (!rc) static uint32_t dec_ref_count(void *context, uint32_t old)
return -EINVAL; {
return old - 1;
}
return sm_ll_insert(ll, b, rc - 1, ev); int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
{
return sm_ll_mutate(ll, b, dec_ref_count, NULL, ev);
} }
int sm_ll_commit(struct ll_disk *ll) int sm_ll_commit(struct ll_disk *ll)
......
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