diff options
| -rw-r--r-- | drivers/md/dm-thin-metadata.c | 30 | ||||
| -rw-r--r-- | drivers/md/dm-thin-metadata.h | 4 |
2 files changed, 15 insertions, 19 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index e9d33ad59df5..ee42d1c52387 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
| @@ -1384,42 +1384,38 @@ static bool __snapshotted_since(struct dm_thin_device *td, uint32_t time) | |||
| 1384 | } | 1384 | } |
| 1385 | 1385 | ||
| 1386 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | 1386 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, |
| 1387 | int can_block, struct dm_thin_lookup_result *result) | 1387 | int can_issue_io, struct dm_thin_lookup_result *result) |
| 1388 | { | 1388 | { |
| 1389 | int r = -EINVAL; | 1389 | int r; |
| 1390 | uint64_t block_time = 0; | ||
| 1391 | __le64 value; | 1390 | __le64 value; |
| 1392 | struct dm_pool_metadata *pmd = td->pmd; | 1391 | struct dm_pool_metadata *pmd = td->pmd; |
| 1393 | dm_block_t keys[2] = { td->id, block }; | 1392 | dm_block_t keys[2] = { td->id, block }; |
| 1394 | struct dm_btree_info *info; | 1393 | struct dm_btree_info *info; |
| 1395 | 1394 | ||
| 1396 | if (can_block) { | ||
| 1397 | down_read(&pmd->root_lock); | ||
| 1398 | info = &pmd->info; | ||
| 1399 | } else if (down_read_trylock(&pmd->root_lock)) | ||
| 1400 | info = &pmd->nb_info; | ||
| 1401 | else | ||
| 1402 | return -EWOULDBLOCK; | ||
| 1403 | |||
| 1404 | if (pmd->fail_io) | 1395 | if (pmd->fail_io) |
| 1405 | goto out; | 1396 | return -EINVAL; |
| 1406 | 1397 | ||
| 1407 | r = dm_btree_lookup(info, pmd->root, keys, &value); | 1398 | down_read(&pmd->root_lock); |
| 1408 | if (!r) | ||
| 1409 | block_time = le64_to_cpu(value); | ||
| 1410 | 1399 | ||
| 1411 | out: | 1400 | if (can_issue_io) { |
| 1412 | up_read(&pmd->root_lock); | 1401 | info = &pmd->info; |
| 1402 | } else | ||
| 1403 | info = &pmd->nb_info; | ||
| 1413 | 1404 | ||
| 1405 | r = dm_btree_lookup(info, pmd->root, keys, &value); | ||
| 1414 | if (!r) { | 1406 | if (!r) { |
| 1407 | uint64_t block_time = 0; | ||
| 1415 | dm_block_t exception_block; | 1408 | dm_block_t exception_block; |
| 1416 | uint32_t exception_time; | 1409 | uint32_t exception_time; |
| 1410 | |||
| 1411 | block_time = le64_to_cpu(value); | ||
| 1417 | unpack_block_time(block_time, &exception_block, | 1412 | unpack_block_time(block_time, &exception_block, |
| 1418 | &exception_time); | 1413 | &exception_time); |
| 1419 | result->block = exception_block; | 1414 | result->block = exception_block; |
| 1420 | result->shared = __snapshotted_since(td, exception_time); | 1415 | result->shared = __snapshotted_since(td, exception_time); |
| 1421 | } | 1416 | } |
| 1422 | 1417 | ||
| 1418 | up_read(&pmd->root_lock); | ||
| 1423 | return r; | 1419 | return r; |
| 1424 | } | 1420 | } |
| 1425 | 1421 | ||
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index e3c857db195a..efedd5a4cd8f 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
| @@ -139,12 +139,12 @@ struct dm_thin_lookup_result { | |||
| 139 | 139 | ||
| 140 | /* | 140 | /* |
| 141 | * Returns: | 141 | * Returns: |
| 142 | * -EWOULDBLOCK iff @can_block is set and would block. | 142 | * -EWOULDBLOCK iff @can_issue_io is set and would issue IO |
| 143 | * -ENODATA iff that mapping is not present. | 143 | * -ENODATA iff that mapping is not present. |
| 144 | * 0 success | 144 | * 0 success |
| 145 | */ | 145 | */ |
| 146 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | 146 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, |
| 147 | int can_block, struct dm_thin_lookup_result *result); | 147 | int can_issue_io, struct dm_thin_lookup_result *result); |
| 148 | 148 | ||
| 149 | /* | 149 | /* |
| 150 | * Obtain an unused block. | 150 | * Obtain an unused block. |
