diff options
author | Joe Thornber <ejt@redhat.com> | 2015-11-05 15:10:11 +0000 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-12-10 10:30:56 -0500 |
commit | 3d5f67332ad9a500857a45397b69a27198720410 (patch) | |
tree | 7911d33cd1cca2e65fefcc5b25141781b5a99693 | |
parent | ed8b45a3679eb49069b094c0711b30833f27c734 (diff) | |
download | linux-3d5f67332ad9a500857a45397b69a27198720410.tar.gz linux-3d5f67332ad9a500857a45397b69a27198720410.tar.bz2 linux-3d5f67332ad9a500857a45397b69a27198720410.zip |
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>
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index c219a053c7f6..7547315ff18a 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -1395,6 +1395,19 @@ static bool __snapshotted_since(struct dm_thin_device *td, uint32_t 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 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; r = dm_btree_lookup(info, pmd->root, keys, &value); - if (!r) { - 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); + if (!r) + unpack_lookup_result(td, value, result); + + up_read(&pmd->root_lock); + return r; +} + +static int dm_thin_find_next_mapped_block(struct dm_thin_device *td, dm_block_t block, + dm_block_t *vblock, + 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); return r; } -/* FIXME: write a more efficient one in btree */ int dm_thin_find_mapped_range(struct dm_thin_device *td, dm_block_t begin, dm_block_t 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) return -ENODATA; - /* - * Find first mapped block. - */ - while (begin < end) { - r = dm_thin_find_block(td, begin, true, &lookup); - if (r) { - if (r != -ENODATA) - return r; - } else - break; - - begin++; - } + r = dm_thin_find_next_mapped_block(td, begin, &begin, &lookup); + if (r) + return r; - if (begin == end) + if (begin >= end) return -ENODATA; *thin_begin = begin; |