mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 00:08:50 +00:00
dm thin metadata: speed up discard of partially mapped volumes
Use dm_btree_lookup_next() to more quickly discard partially mapped volumes. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
ed8b45a367
commit
3d5f67332a
@ -1395,6 +1395,19 @@ static bool __snapshotted_since(struct dm_thin_device *td, uint32_t time)
|
|||||||
return td->snapshotted_time > time;
|
return td->snapshotted_time > time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unpack_lookup_result(struct dm_thin_device *td, __le64 value,
|
||||||
|
struct dm_thin_lookup_result *result)
|
||||||
|
{
|
||||||
|
uint64_t block_time = 0;
|
||||||
|
dm_block_t exception_block;
|
||||||
|
uint32_t exception_time;
|
||||||
|
|
||||||
|
block_time = le64_to_cpu(value);
|
||||||
|
unpack_block_time(block_time, &exception_block, &exception_time);
|
||||||
|
result->block = exception_block;
|
||||||
|
result->shared = __snapshotted_since(td, exception_time);
|
||||||
|
}
|
||||||
|
|
||||||
int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
|
int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
|
||||||
int can_issue_io, struct dm_thin_lookup_result *result)
|
int can_issue_io, struct dm_thin_lookup_result *result)
|
||||||
{
|
{
|
||||||
@ -1416,23 +1429,36 @@ int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block,
|
|||||||
info = &pmd->nb_info;
|
info = &pmd->nb_info;
|
||||||
|
|
||||||
r = dm_btree_lookup(info, pmd->root, keys, &value);
|
r = dm_btree_lookup(info, pmd->root, keys, &value);
|
||||||
if (!r) {
|
if (!r)
|
||||||
uint64_t block_time = 0;
|
unpack_lookup_result(td, value, result);
|
||||||
dm_block_t exception_block;
|
|
||||||
uint32_t exception_time;
|
up_read(&pmd->root_lock);
|
||||||
|
return r;
|
||||||
block_time = le64_to_cpu(value);
|
}
|
||||||
unpack_block_time(block_time, &exception_block,
|
|
||||||
&exception_time);
|
static int dm_thin_find_next_mapped_block(struct dm_thin_device *td, dm_block_t block,
|
||||||
result->block = exception_block;
|
dm_block_t *vblock,
|
||||||
result->shared = __snapshotted_since(td, exception_time);
|
struct dm_thin_lookup_result *result)
|
||||||
}
|
{
|
||||||
|
int r;
|
||||||
|
__le64 value;
|
||||||
|
struct dm_pool_metadata *pmd = td->pmd;
|
||||||
|
dm_block_t keys[2] = { td->id, block };
|
||||||
|
|
||||||
|
down_read(&pmd->root_lock);
|
||||||
|
if (pmd->fail_io) {
|
||||||
|
up_read(&pmd->root_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dm_btree_lookup_next(&pmd->info, pmd->root, keys, vblock, &value);
|
||||||
|
if (!r)
|
||||||
|
unpack_lookup_result(td, value, result);
|
||||||
|
|
||||||
up_read(&pmd->root_lock);
|
up_read(&pmd->root_lock);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: write a more efficient one in btree */
|
|
||||||
int dm_thin_find_mapped_range(struct dm_thin_device *td,
|
int dm_thin_find_mapped_range(struct dm_thin_device *td,
|
||||||
dm_block_t begin, dm_block_t end,
|
dm_block_t begin, dm_block_t end,
|
||||||
dm_block_t *thin_begin, dm_block_t *thin_end,
|
dm_block_t *thin_begin, dm_block_t *thin_end,
|
||||||
@ -1445,21 +1471,11 @@ int dm_thin_find_mapped_range(struct dm_thin_device *td,
|
|||||||
if (end < begin)
|
if (end < begin)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
/*
|
r = dm_thin_find_next_mapped_block(td, begin, &begin, &lookup);
|
||||||
* Find first mapped block.
|
if (r)
|
||||||
*/
|
return r;
|
||||||
while (begin < end) {
|
|
||||||
r = dm_thin_find_block(td, begin, true, &lookup);
|
|
||||||
if (r) {
|
|
||||||
if (r != -ENODATA)
|
|
||||||
return r;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
|
|
||||||
begin++;
|
if (begin >= end)
|
||||||
}
|
|
||||||
|
|
||||||
if (begin == end)
|
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
*thin_begin = begin;
|
*thin_begin = begin;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user