aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2015-11-05 10:10:11 -0500
committerMike Snitzer <snitzer@redhat.com>2015-12-10 10:30:56 -0500
commit3d5f67332ad9a500857a45397b69a27198720410 (patch)
tree7911d33cd1cca2e65fefcc5b25141781b5a99693 /drivers/md
parented8b45a3679eb49069b094c0711b30833f27c734 (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.c66
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
1398static 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
1398int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, 1411int 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); 1439static 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 */
1436int dm_thin_find_mapped_range(struct dm_thin_device *td, 1462int 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;