diff options
author | Joe Thornber <ejt@redhat.com> | 2016-09-15 09:23:46 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-09-22 11:15:02 -0400 |
commit | 4e781b498ee5008ede91362d91404a362e7a46b3 (patch) | |
tree | 039f3914f839b455759253fb0395a639a1912dae /drivers/md/dm-cache-metadata.c | |
parent | dd6a77d99859ab963503e67372ed278fe8ceab26 (diff) |
dm cache: speed up writing of the hint array
It's far quicker to always delete the hint array and recreate with
dm_array_new() because we avoid the copying caused by mutation.
Also simplifies the policy interface, replacing the walk_hints() with
the simpler get_hint().
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-cache-metadata.c')
-rw-r--r-- | drivers/md/dm-cache-metadata.c | 80 |
1 files changed, 27 insertions, 53 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 3970cda10080..a60f10a0ee0a 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c | |||
@@ -1368,10 +1368,24 @@ int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd, | |||
1368 | 1368 | ||
1369 | /*----------------------------------------------------------------*/ | 1369 | /*----------------------------------------------------------------*/ |
1370 | 1370 | ||
1371 | static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) | 1371 | static int get_hint(uint32_t index, void *value_le, void *context) |
1372 | { | ||
1373 | uint32_t value; | ||
1374 | struct dm_cache_policy *policy = context; | ||
1375 | |||
1376 | value = policy_get_hint(policy, to_cblock(index)); | ||
1377 | *((__le32 *) value_le) = cpu_to_le32(value); | ||
1378 | |||
1379 | return 0; | ||
1380 | } | ||
1381 | |||
1382 | /* | ||
1383 | * It's quicker to always delete the hint array, and recreate with | ||
1384 | * dm_array_new(). | ||
1385 | */ | ||
1386 | static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) | ||
1372 | { | 1387 | { |
1373 | int r; | 1388 | int r; |
1374 | __le32 value; | ||
1375 | size_t hint_size; | 1389 | size_t hint_size; |
1376 | const char *policy_name = dm_cache_policy_get_name(policy); | 1390 | const char *policy_name = dm_cache_policy_get_name(policy); |
1377 | const unsigned *policy_version = dm_cache_policy_get_version(policy); | 1391 | const unsigned *policy_version = dm_cache_policy_get_version(policy); |
@@ -1380,63 +1394,23 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po | |||
1380 | (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) | 1394 | (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) |
1381 | return -EINVAL; | 1395 | return -EINVAL; |
1382 | 1396 | ||
1383 | if (!policy_unchanged(cmd, policy)) { | 1397 | strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); |
1384 | strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); | 1398 | memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); |
1385 | memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); | ||
1386 | 1399 | ||
1387 | hint_size = dm_cache_policy_get_hint_size(policy); | 1400 | hint_size = dm_cache_policy_get_hint_size(policy); |
1388 | if (!hint_size) | 1401 | if (!hint_size) |
1389 | return 0; /* short-circuit hints initialization */ | 1402 | return 0; /* short-circuit hints initialization */ |
1390 | cmd->policy_hint_size = hint_size; | 1403 | cmd->policy_hint_size = hint_size; |
1391 | 1404 | ||
1392 | if (cmd->hint_root) { | 1405 | if (cmd->hint_root) { |
1393 | r = dm_array_del(&cmd->hint_info, cmd->hint_root); | 1406 | r = dm_array_del(&cmd->hint_info, cmd->hint_root); |
1394 | if (r) | ||
1395 | return r; | ||
1396 | } | ||
1397 | |||
1398 | r = dm_array_empty(&cmd->hint_info, &cmd->hint_root); | ||
1399 | if (r) | 1407 | if (r) |
1400 | return r; | 1408 | return r; |
1401 | |||
1402 | value = cpu_to_le32(0); | ||
1403 | __dm_bless_for_disk(&value); | ||
1404 | r = dm_array_resize(&cmd->hint_info, cmd->hint_root, 0, | ||
1405 | from_cblock(cmd->cache_blocks), | ||
1406 | &value, &cmd->hint_root); | ||
1407 | if (r) | ||
1408 | return r; | ||
1409 | } | ||
1410 | |||
1411 | return 0; | ||
1412 | } | ||
1413 | |||
1414 | static int save_hint(void *context, dm_cblock_t cblock, dm_oblock_t oblock, uint32_t hint) | ||
1415 | { | ||
1416 | struct dm_cache_metadata *cmd = context; | ||
1417 | __le32 value = cpu_to_le32(hint); | ||
1418 | int r; | ||
1419 | |||
1420 | __dm_bless_for_disk(&value); | ||
1421 | |||
1422 | r = dm_array_set_value(&cmd->hint_info, cmd->hint_root, | ||
1423 | from_cblock(cblock), &value, &cmd->hint_root); | ||
1424 | cmd->changed = true; | ||
1425 | |||
1426 | return r; | ||
1427 | } | ||
1428 | |||
1429 | static int write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) | ||
1430 | { | ||
1431 | int r; | ||
1432 | |||
1433 | r = begin_hints(cmd, policy); | ||
1434 | if (r) { | ||
1435 | DMERR("begin_hints failed"); | ||
1436 | return r; | ||
1437 | } | 1409 | } |
1438 | 1410 | ||
1439 | return policy_walk_mappings(policy, save_hint, cmd); | 1411 | return dm_array_new(&cmd->hint_info, &cmd->hint_root, |
1412 | from_cblock(cmd->cache_blocks), | ||
1413 | get_hint, policy); | ||
1440 | } | 1414 | } |
1441 | 1415 | ||
1442 | int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) | 1416 | int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) |