summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-cache-metadata.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2016-09-15 09:23:46 -0400
committerMike Snitzer <snitzer@redhat.com>2016-09-22 11:15:02 -0400
commit4e781b498ee5008ede91362d91404a362e7a46b3 (patch)
tree039f3914f839b455759253fb0395a639a1912dae /drivers/md/dm-cache-metadata.c
parentdd6a77d99859ab963503e67372ed278fe8ceab26 (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.c80
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
1371static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) 1371static 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 */
1386static 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
1414static 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
1429static 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
1442int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy) 1416int dm_cache_write_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)