diff options
author | Joe Thornber <ejt@redhat.com> | 2015-11-05 10:10:11 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-12-10 10:30:56 -0500 |
commit | 3d5f67332ad9a500857a45397b69a27198720410 (patch) | |
tree | 7911d33cd1cca2e65fefcc5b25141781b5a99693 /drivers/md | |
parent | ed8b45a3679eb49069b094c0711b30833f27c734 (diff) |
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>
Diffstat (limited to 'drivers/md')
-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) | |||
1395 | return td->snapshotted_time > time; | 1395 | return td->snapshotted_time > time; |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | static void unpack_lookup_result(struct dm_thin_device *td, __le64 value, | ||
1399 | struct dm_thin_lookup_result *result) | ||
1400 | { | ||
1401 | uint64_t block_time = 0; | ||
1402 | dm_block_t exception_block; | ||
1403 | uint32_t exception_time; | ||
1404 | |||
1405 | block_time = le64_to_cpu(value); | ||
1406 | unpack_block_time(block_time, &exception_block, &exception_time); | ||
1407 | result->block = exception_block; | ||
1408 | result->shared = __snapshotted_since(td, exception_time); | ||
1409 | } | ||
1410 | |||
1398 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | 1411 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, |
1399 | int can_issue_io, struct dm_thin_lookup_result *result) | 1412 | int can_issue_io, struct dm_thin_lookup_result *result) |
1400 | { | 1413 | { |
@@ -1416,23 +1429,36 @@ int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | |||
1416 | info = &pmd->nb_info; | 1429 | info = &pmd->nb_info; |
1417 | 1430 | ||
1418 | r = dm_btree_lookup(info, pmd->root, keys, &value); | 1431 | r = dm_btree_lookup(info, pmd->root, keys, &value); |
1419 | if (!r) { | 1432 | if (!r) |
1420 | uint64_t block_time = 0; | 1433 | unpack_lookup_result(td, value, result); |
1421 | dm_block_t exception_block; | 1434 | |
1422 | uint32_t exception_time; | 1435 | up_read(&pmd->root_lock); |
1423 | 1436 | return r; | |
1424 | block_time = le64_to_cpu(value); | 1437 | } |
1425 | unpack_block_time(block_time, &exception_block, | 1438 | |
1426 | &exception_time); | 1439 | static int dm_thin_find_next_mapped_block(struct dm_thin_device *td, dm_block_t block, |
1427 | result->block = exception_block; | 1440 | dm_block_t *vblock, |
1428 | result->shared = __snapshotted_since(td, exception_time); | 1441 | struct dm_thin_lookup_result *result) |
1442 | { | ||
1443 | int r; | ||
1444 | __le64 value; | ||
1445 | struct dm_pool_metadata *pmd = td->pmd; | ||
1446 | dm_block_t keys[2] = { td->id, block }; | ||
1447 | |||
1448 | down_read(&pmd->root_lock); | ||
1449 | if (pmd->fail_io) { | ||
1450 | up_read(&pmd->root_lock); | ||
1451 | return -EINVAL; | ||
1429 | } | 1452 | } |
1430 | 1453 | ||
1454 | r = dm_btree_lookup_next(&pmd->info, pmd->root, keys, vblock, &value); | ||
1455 | if (!r) | ||
1456 | unpack_lookup_result(td, value, result); | ||
1457 | |||
1431 | up_read(&pmd->root_lock); | 1458 | up_read(&pmd->root_lock); |
1432 | return r; | 1459 | return r; |
1433 | } | 1460 | } |
1434 | 1461 | ||
1435 | /* FIXME: write a more efficient one in btree */ | ||
1436 | int dm_thin_find_mapped_range(struct dm_thin_device *td, | 1462 | int dm_thin_find_mapped_range(struct dm_thin_device *td, |
1437 | dm_block_t begin, dm_block_t end, | 1463 | dm_block_t begin, dm_block_t end, |
1438 | dm_block_t *thin_begin, dm_block_t *thin_end, | 1464 | 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, | |||
1445 | if (end < begin) | 1471 | if (end < begin) |
1446 | return -ENODATA; | 1472 | return -ENODATA; |
1447 | 1473 | ||
1448 | /* | 1474 | r = dm_thin_find_next_mapped_block(td, begin, &begin, &lookup); |
1449 | * Find first mapped block. | 1475 | if (r) |
1450 | */ | 1476 | return r; |
1451 | while (begin < end) { | ||
1452 | r = dm_thin_find_block(td, begin, true, &lookup); | ||
1453 | if (r) { | ||
1454 | if (r != -ENODATA) | ||
1455 | return r; | ||
1456 | } else | ||
1457 | break; | ||
1458 | |||
1459 | begin++; | ||
1460 | } | ||
1461 | 1477 | ||
1462 | if (begin == end) | 1478 | if (begin >= end) |
1463 | return -ENODATA; | 1479 | return -ENODATA; |
1464 | 1480 | ||
1465 | *thin_begin = begin; | 1481 | *thin_begin = begin; |