diff options
author | Joe Thornber <ejt@redhat.com> | 2015-04-16 07:47:21 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-06-11 17:13:03 -0400 |
commit | a5d895a90bf57e5fe87edf48dd1852e7292d570d (patch) | |
tree | 9ac33ffeca4546e80c4975dc41f320b7519661f8 | |
parent | 4ec331c3ea7ec94f28aa1c62a279cfa1cfe3c91b (diff) |
dm thin metadata: add dm_thin_find_mapped_range()
Retrieve the next run of contiguously mapped blocks. Useful for working
out where to break up IO.
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 | 57 | ||||
-rw-r--r-- | drivers/md/dm-thin-metadata.h | 9 |
2 files changed, 66 insertions, 0 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index cb6dd055053d..94cf0db8a22e 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -1417,6 +1417,63 @@ int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | |||
1417 | return r; | 1417 | return r; |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | /* FIXME: write a more efficient one in btree */ | ||
1421 | int dm_thin_find_mapped_range(struct dm_thin_device *td, | ||
1422 | dm_block_t begin, dm_block_t end, | ||
1423 | dm_block_t *thin_begin, dm_block_t *thin_end, | ||
1424 | dm_block_t *pool_begin, bool *maybe_shared) | ||
1425 | { | ||
1426 | int r; | ||
1427 | dm_block_t pool_end; | ||
1428 | struct dm_thin_lookup_result lookup; | ||
1429 | |||
1430 | if (end < begin) | ||
1431 | return -ENODATA; | ||
1432 | |||
1433 | /* | ||
1434 | * Find first mapped block. | ||
1435 | */ | ||
1436 | while (begin < end) { | ||
1437 | r = dm_thin_find_block(td, begin, true, &lookup); | ||
1438 | if (r) { | ||
1439 | if (r != -ENODATA) | ||
1440 | return r; | ||
1441 | } else | ||
1442 | break; | ||
1443 | |||
1444 | begin++; | ||
1445 | } | ||
1446 | |||
1447 | if (begin == end) | ||
1448 | return -ENODATA; | ||
1449 | |||
1450 | *thin_begin = begin; | ||
1451 | *pool_begin = lookup.block; | ||
1452 | *maybe_shared = lookup.shared; | ||
1453 | |||
1454 | begin++; | ||
1455 | pool_end = *pool_begin + 1; | ||
1456 | while (begin != end) { | ||
1457 | r = dm_thin_find_block(td, begin, true, &lookup); | ||
1458 | if (r) { | ||
1459 | if (r == -ENODATA) | ||
1460 | break; | ||
1461 | else | ||
1462 | return r; | ||
1463 | } | ||
1464 | |||
1465 | if ((lookup.block != pool_end) || | ||
1466 | (lookup.shared != *maybe_shared)) | ||
1467 | break; | ||
1468 | |||
1469 | pool_end++; | ||
1470 | begin++; | ||
1471 | } | ||
1472 | |||
1473 | *thin_end = begin; | ||
1474 | return 0; | ||
1475 | } | ||
1476 | |||
1420 | static int __insert(struct dm_thin_device *td, dm_block_t block, | 1477 | static int __insert(struct dm_thin_device *td, dm_block_t block, |
1421 | dm_block_t data_block) | 1478 | dm_block_t data_block) |
1422 | { | 1479 | { |
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index fac01a96d303..f11f14095b93 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
@@ -147,6 +147,15 @@ int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, | |||
147 | int can_issue_io, struct dm_thin_lookup_result *result); | 147 | int can_issue_io, struct dm_thin_lookup_result *result); |
148 | 148 | ||
149 | /* | 149 | /* |
150 | * Retrieve the next run of contiguously mapped blocks. Useful for working | ||
151 | * out where to break up IO. Returns 0 on success, < 0 on error. | ||
152 | */ | ||
153 | int dm_thin_find_mapped_range(struct dm_thin_device *td, | ||
154 | dm_block_t begin, dm_block_t end, | ||
155 | dm_block_t *thin_begin, dm_block_t *thin_end, | ||
156 | dm_block_t *pool_begin, bool *maybe_shared); | ||
157 | |||
158 | /* | ||
150 | * Obtain an unused block. | 159 | * Obtain an unused block. |
151 | */ | 160 | */ |
152 | int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result); | 161 | int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result); |