Commit f177940a authored by Joe Thornber's avatar Joe Thornber Committed by Mike Snitzer

dm cache metadata: switch to using the new cursor api for loading metadata

This change offers a pretty significant performance improvement.
Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent fdd1315a
...@@ -140,6 +140,13 @@ struct dm_cache_metadata { ...@@ -140,6 +140,13 @@ struct dm_cache_metadata {
* the device. * the device.
*/ */
bool fail_io:1; bool fail_io:1;
/*
* These structures are used when loading metadata. They're too
* big to put on the stack.
*/
struct dm_array_cursor mapping_cursor;
struct dm_array_cursor hint_cursor;
}; };
/*------------------------------------------------------------------- /*-------------------------------------------------------------------
...@@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd, ...@@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd,
hints_array_initialized(cmd); hints_array_initialized(cmd);
} }
static int __load_mapping(void *context, uint64_t cblock, void *leaf) static int __load_mapping(struct dm_cache_metadata *cmd,
uint64_t cb, bool hints_valid,
struct dm_array_cursor *mapping_cursor,
struct dm_array_cursor *hint_cursor,
load_mapping_fn fn, void *context)
{ {
int r = 0; int r = 0;
bool dirty;
__le64 value; __le64 mapping;
__le32 hint_value = 0; __le32 hint = 0;
__le64 *mapping_value_le;
__le32 *hint_value_le;
dm_oblock_t oblock; dm_oblock_t oblock;
unsigned flags; unsigned flags;
struct thunk *thunk = context;
struct dm_cache_metadata *cmd = thunk->cmd;
memcpy(&value, leaf, sizeof(value)); dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
unpack_value(value, &oblock, &flags); memcpy(&mapping, mapping_value_le, sizeof(mapping));
unpack_value(mapping, &oblock, &flags);
if (flags & M_VALID) { if (flags & M_VALID) {
if (thunk->hints_valid) { if (hints_valid) {
r = dm_array_get_value(&cmd->hint_info, cmd->hint_root, dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
cblock, &hint_value); memcpy(&hint, hint_value_le, sizeof(hint));
if (r && r != -ENODATA)
return r;
} }
dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true; r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY,
r = thunk->fn(thunk->context, oblock, to_cblock(cblock), le32_to_cpu(hint), hints_valid);
dirty, le32_to_cpu(hint_value), thunk->hints_valid); if (r)
DMERR("policy couldn't load cblock");
} }
return r; return r;
...@@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd, ...@@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd,
struct dm_cache_policy *policy, struct dm_cache_policy *policy,
load_mapping_fn fn, void *context) load_mapping_fn fn, void *context)
{ {
struct thunk thunk; int r;
uint64_t cb;
thunk.fn = fn; bool hints_valid = hints_array_available(cmd, policy);
thunk.context = context;
thunk.cmd = cmd; if (from_cblock(cmd->cache_blocks) == 0)
thunk.respect_dirty_flags = cmd->clean_when_opened; /* Nothing to do */
thunk.hints_valid = hints_array_available(cmd, policy); return 0;
return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); r = dm_array_cursor_begin(&cmd->info, cmd->root, &cmd->mapping_cursor);
if (r)
return r;
if (hints_valid) {
r = dm_array_cursor_begin(&cmd->hint_info, cmd->hint_root, &cmd->hint_cursor);
if (r) {
dm_array_cursor_end(&cmd->mapping_cursor);
return r;
}
}
for (cb = 0; ; cb++) {
r = __load_mapping(cmd, cb, hints_valid,
&cmd->mapping_cursor, &cmd->hint_cursor,
fn, context);
if (r)
goto out;
/*
* We need to break out before we move the cursors.
*/
if (cb >= (from_cblock(cmd->cache_blocks) - 1))
break;
r = dm_array_cursor_next(&cmd->mapping_cursor);
if (r) {
DMERR("dm_array_cursor_next for mapping failed");
goto out;
}
if (hints_valid) {
r = dm_array_cursor_next(&cmd->hint_cursor);
if (r) {
DMERR("dm_array_cursor_next for hint failed");
goto out;
}
}
}
out:
dm_array_cursor_end(&cmd->mapping_cursor);
if (hints_valid)
dm_array_cursor_end(&cmd->hint_cursor);
return r;
} }
int dm_cache_load_mappings(struct dm_cache_metadata *cmd, int dm_cache_load_mappings(struct dm_cache_metadata *cmd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment